[2] [DFN[[RUBYB[タスクキュー]@en[task queue]]]]は、[[イベントループ]]における[[タスク]]の[[順序付き]]の[[リスト]]
([[キュー]]) です。
[[Webブラウザー]]内に常にいくつか存在します。

* 仕様書

[REFS[
- [9] [CITE@en-US-x-hixie[HTML Standard]] ([TIME[2016-12-06 07:17:59 +09:00]]) <https://html.spec.whatwg.org/#event-loops>
-- [1] '''[CITE@en-US-x-hixie[HTML Standard]] ([TIME[2012-03-28 21:58:58 +09:00]] 版) <http://www.whatwg.org/specs/web-apps/current-work/#task-queue>'''
-- [19] [CITE@en-US-x-hixie[HTML Standard]] ([TIME[2012-03-28 21:58:58 +09:00]] 版) <http://www.whatwg.org/specs/web-apps/current-work/#the-event-loop>
-- [10] [CITE@en-US-x-hixie[HTML Standard]] ([TIME[2016-12-06 07:17:59 +09:00]]) <https://html.spec.whatwg.org/#worker-event-loop>
-- [44] [CITE@en-US-x-hixie[HTML Standard]] ([TIME[2012-03-28 21:58:58 +09:00]] 版) <https://www.whatwg.org/specs/web-apps/current-work/#task-source>
-- [45] [CITE@en-US-x-hixie[HTML Standard]] ([TIME[2013-02-09 02:07:40 +09:00]] 版) <https://www.whatwg.org/specs/web-apps/current-work/#unshipped-port-message-queue>
- [78] [CITE@en-US-x-hixie[HTML Standard]] ([TIME[2016-12-06 07:17:59 +09:00]]) <https://html.spec.whatwg.org/#parsing-main-incdata>
- [75] [CITE@en[Service Workers Nightly]] ([TIME[2017-02-16 20:10:49 +09:00]]) <https://w3c.github.io/ServiceWorker/#dfn-service-worker-registration-task-queue>
- [94] [CITE@en[Service Workers Nightly]] ([TIME[2017-03-02 15:00:14 +09:00]]) <https://w3c.github.io/ServiceWorker/#dfn-client-message-queue>
]REFS]

* 意味

[4] [[タスクキュー]]は、[[タスク]]の[[集合]]です [SRC[>>1]]。
0個以上の[[タスク]]を入れたり出したりできます。
原則的に [[FIFO]] なので[[キュー]]と呼ばれていますが、
[[event loop step 1]] のようにそれ以外の特別な操作もあるため、
現在の [CITE[HTML Standard]] は[[集合]]と定義しています [SRC[>>1]]。
なお [CITE[Infra Standard]] によれば [[Web]]
における[[集合]]は[[順序付きリスト]]です。

[5] 基本的に未実行の[[タスク]]は[[タスクキュー]]に入れられて待機状態となります。
一つの[[タスク]]が複数の[[タスクキュー]]に同時に含まれることはありません。

* 文脈

[18] [[イベントループ]]は、1つ[[以上]]の[DFN[[F[タスクキュー群]]]]を持ちます [SRC[>>1]]。

[31] [[イベントループ]]がいくつ[[タスクキュー]]を持つかは、[[実装依存]]です。

[EG[
[12] 例えば、[[マウス操作]]その他の[[利用者]]の操作 ([[利用者対話タスク源]])
の[[タスクキュー]]と、それ以外の[[タスクキュー]]とで2つ用意し、
[[利用者]]の操作の[[タスクキュー]]を優先的に処理する、という戦略を採ることができます。
[SRC[>>1]]
]EG]

[32] ある[[イベントループ]]で、
ある[[タスク源]]から来た[[タスク]]をどの[[タスクキュー]]に追加するかは、
[[実装依存]]の方法で固定しなければ[MUST[なりません]] [SRC[>>1]] (>>3)。

[84] 実装戦略によっては実行時に[[タスクキュー]]が増減するかもしれませんが、
同じ[[タスク源]]の[[タスク]]は同じ[[タスクキュー]]に入れなければならないという原則は歪められません。

-*-*-

[76] [[サービスワーカー登録]]は、1つ[[以上]]の[DFN[[F[[RUBYB[[[タスクキュー群]]]@en[task queues]]]]]]を持ちます。
これは[[活性ワーカー]]が動作していない間に[[タスク]]を保持しておくもので、
これ自体を使って[[タスク]]を実行するものではありません。
[SRC[>>75]]

;;
[7] 同じく[[タスク]]の[[キュー]]であっても、
[FIG(list middle)[
- [[セッション履歴探索キュー]]
- [[マイクロタスクキュー]]
- [[クライアントメッセージキュー]]
- [[ポートメッセージキュー]]
- [[未出荷済みポートメッセージキュー]]
- [[pending application cache download process tasks]]
]FIG]
... は定義上[[タスクキュー]]とは異なるものです。
([[タスクキュー]]は[[データ型]]ではなく、[[イベントループ]]のフィールド名と捉えるべきもののようです。)


* タスク源

[46] 各[[タスク]]は、何らかの[DFN[[RUBYB[タスク源]@en[task source]]]]から[RUBYB[来る]@en[come]]ものと定義されます
[SRC[>>44]]。

[102] 
[[タスク]]は、
[DFN[[F[[RUBYB[[[源]]][source]]]]]]を持ちます。
[F[源]]は、
[[タスク源]]のいずれかであって、
関連する[[タスク]]を集団化し[[直列化]]するために使われます。
[SRC[>>9]]

[103] 
ある[[イベントループ]]においてある[[タスク源]]は、
当該[[イベントループ]]の特定の[[タスクキュー]]と関連付けられなければ[MUST[なりません]]
[SRC[>>9]]。
この関係は[[イベントループ]]が開始された時から終了する時まで変わることがありません。

[104] 
いわば[[タスク源]]は[[タスクキュー]]のラベルのような働きを持っています。
[[タスク源]]には1つ[[タスクキュー]]がありますが、
[[タスクキュー]]の[[タスク源]]は1つとは限りません。
複数の[[タスク源]]が同じ[[タスクキュー]]を共有することがあります。
すべての[[タスク源]]が独立した[[タスクキュー]]を持つ状態が、
[[タスクキュー]]を最大限分割した状態といえます。


[61] [[タスクキュー]]は[[タスク源]]によって分けられており、
同じ[[タスク源]]の[[タスク]]同士の実行順序は[[タスクキュー]]への追加順序となることが保証されます。

[62] [[タスク源]]は、追加時に[[タスクキュー]]の決定に使われる他、
何らかの理由で[[タスクキュー]]から[[タスク]]を削除する条件として使われることもあります。

[49] [[タスク源]]としては次のものがあります。
[FIG(list middle)[
- [[DOM操作タスク源]]
- [[利用者対話タスク源]]
- [[ネットワーク処理タスク源]]
- [[履歴探索タスク源]]
- [[媒体要素イベントタスク源]]
- [[画布blob直列化タスク源]]
- [[画布更新タスク源]]
- [[タイマー・タスク源]]
- [[遠隔イベント・タスク源]]
- [[WebSocketタスク源]]
- [[ポートメッセージキュー]]
- [[未出荷済みポートメッセージキュー]]
- [[クライアントメッセージキュー]]
- [[[CODE(DOMi)@en[XMLHttpRequest]]タスク源]]
- [[[CODE(DOMi)@en[FileReader]]タスク源]]
- [[データベース・アクセス・タスク源]]
- [[埋め込みタスク源]]
- [[WebGLタスク源]]
- [[マイクロタスクタスク源]]
- [[フォント読み込みタスク源]]
- [[application life-cycle task source]]
- [[アイドルタスクタスク源]]
- [[センサータスク源]]
- [[handle fetch task source]]

[HISTORY[
- [[投稿済みメッセージタスク源]]
- [[雛形タスク源]]
- [[[CODE(DOMi)@en[FileSaver]]タスク源]]
- [[装置タスク源]]
- [[[CODE(DOMi)@en[PendingOp]]タスク源]]
]HISTORY]
]FIG]

[53] [[タスク源]]の一覧は >>54 にあります。

[REFS[
- [54] [CITE[data-web-defs/data/browsers.json at master · manakai/data-web-defs]] ([TIME[2014-04-09 13:08:57 +09:00]] 版) <https://github.com/manakai/data-web-defs/blob/master/data/browsers.json>
]REFS]



[50] ほとんどの[[タスク源]]は[[イベントループ]]に1つずつ存在していますが、
[[ポートメッセージキュー]]は[[著者]]が [CODE(DOMi)@en[[[MessagePort]]]]
[[オブジェクト]]を作成することによって任意個作成されます。
[[クライアントメッセージキュー]]は [CODE(DOMi)@en[ServiceWorkerContainer]]
[[オブジェクト]]の数だけ存在します。
[[媒体要素イベントタスク源]]と
[[[CODE(DOMi)@en[XMLHttpRequest]]タスク源]] もオブジェクトごとに存在します。
[[[CODE(DOMi)@en[FileReader]]タスク源]]、[[[CODE(DOMi)@en[FileSaver]]タスク源]]もオブジェクトごとに存在するようです。

[51] [[未出荷済みポートメッセージキュー]]は[RUBYB[仮想]@en[virtual]]タスク源 [SRC[>>54]]
であり、その[[タスク]]は[[ポートメッセージキュー]]にも[[未出荷済みポートメッセージキュー]]にも属するという特殊な状態になっています。
[[未出荷済みポートメッセージキュー]]は[[イベントループ]]ごとに1つだけあります [SRC[>>45]]。

;; [52] 転送していない [CODE(DOMi)@en[[[MessagePort]]]] では必ず同じ順序で[[タスク]]が実行されることを保証し、
転送してしまった [CODE(DOMi)@en[[[MessagePort]]]] では任意の実行順序となることを認めるためにこのような複雑な構造になっています。

;; [88] 同じ[[タスク源]]なら同じ[[タスクキュー]]を使うとの制約から、
[[未出荷済みポートメッセージキュー]]に入る[[タスク]]は ([[ポートメッセージキュー]]に関わらず)
同じ[[タスクキュー]]に入るものとしなければなりません。[[出荷]]済みの[[ポートメッセージキュー]]にはこの制約はありません。

** マイクロタスクとの関係

[58] [[マイクロタスク]]の[[タスク源]]はすべて[[マイクロタスクタスク源]]と定義されています。

[59] [[マイクロタスク]]には[[タスクキュー]]とは別の[[マイクロタスクキュー]]が存在しています。
これは[[マイクロタスク源]]の[[タスク]] ([[マイクロタスク]]) を実行する[[タスクキュー]]とは別のものです。

* タスクキューの構造

[83] [[仕様書]]上、[[タスクキュー]]は[[タスク]]の[[集合]]であるとしか説明されていません。
しかし、[[タスクキュー]]上の[[タスク]]には、[F[源][タスク源]]、[F[文書][タスク]]、[F[fetch]]
という情報が関連付けられていて、これが[[タスクキュー]]が関わる色々な演算で重要な役目を持ちます。

[85] [[タスクキュー]]は、[F[源][タスク源]]、[F[文書][タスク]]、[F[fetch]] という情報を持った[[タスク]]の[[キュー]]であるが、
通常の[[キュー]]とは異なる特殊な[[演算]]も持つ、と解釈することもできますし、
[F[源][タスク源]]、[F[文書][タスク]]、[F[fetch]] をキーとする[[タスク]]のリスト
([DFN[タスクキュー部分リスト]]) をいくつか重ね合わせて全体として[[順序]]を持つ[[リスト]]として捉えたものが[[タスクキュー]]である、
と解釈することもできそうです。

[86] [[ポートメッセージキュー]]や[[クライアントメッセージキュー]]は、[[タスクキュー部分リスト]]の一種であると解せます。

[87] [[未出荷済みポートメッセージキュー]]は、いくつかの[[ポートメッセージキュー]]を束ねたものと捉えることができます。
ただし、[[未出荷済みポートメッセージキュー]]の[[タスク]]と各[[ポートメッセージキュー]]の[[タスク]]が異なる[[タスクキュー]]を利用する場合を考えると、
事情は若干複雑化します。

;; [63] [[ポートメッセージキュー]]も参照。

[65] [[タスクキュー部分リスト]]は、[F[状態]]を持ちます (>>66)。

* 追加

[11] 
[DFN[[RUBYB[タスクをキューに[RUBY[追][つい]][RUBY[加][か]]]@en[queue a task]]]]する処理
[SRC[>>1]]
は、新たに[[タスク]]の実行を予定するものです。

[43] [[タスク]]は、その処理に関係する[[イベントループ]]に追加されます。
[[Webブラウザー]]が複数の[[イベントループ]]を持つ場合、
処理対象の[[文書]]や[[ワーカー]]を担当している[[イベントループ]]の[[タスクキュー]]に追加されることになります。

[3] [[タスク]]は、その出自である[[タスク源]]によって決まる[[タスクキュー]]に追加されます。
[[イベントループ]]が複数の[[タスクキュー]]を持つ場合、
同じ[[タスク源]]からの[[タスク]]は必ず同じ[[タスクキュー]]に追加され、
相互の順序は保持されますが、
異なる[[タスク源]]からの[[タスク]]は異なる[[タスクキュー]]に追加されるかもしれないため、
順序は保証されません。


[37] [[タスクをキューに追加]]する処理は、
次の引数を受け取ります。

[FIG(list members)[
: [VAR[源]] :
[[タスク源]]。
: [VAR[イベントループ]] : 
[[イベントループ]]。
[[仕様書]]はこの[[引数]]を省略可能としており、
省略された場合[[暗示イベントループ]]を意味するとしています [SRC[>>1]]。
: [VAR[手順群]] :
[[手順群]]の系列。 
: [VAR[文脈]] : 
[[要素]]、[[閲覧文脈]]、[[環境設定群オブジェクト]]のいずれか。
あるいは[[スクリプト]]が指定された場合、その[F[設定群オブジェクト]] [SRC[>>1]]。
[[タスクをキューに追加]]の呼び出し元を意味しています。
([[クライアントメッセージキュー]]の場合は、[[クライアントメッセージキュー]]の[F[関連設定群オブジェクト]] [SRC[>>94]]。)
: [VAR[文書]] : 
[[文書]]。
[[仕様書]]はこの[[引数]]を省略可能としており、
省略された場合に[VAR[イベントループ]]と[VAR[文脈]]についての[[暗示文書]]を意味するとしています [SRC[>>1]]。
: [VAR[fetch]] :
[[fetch]] または [CODE[null]]。 [[fetch]] から[[タスクをキューに追加]]する場合には、
その [[fetch]] の[[実現値]]となります。既定値は [CODE[null]]。
: [VAR[捨てる処理]] : [[handle fetch]] や [[Install]] で指定されます。
]FIG]

[38] [[タスクをキューに追加]]する処理は、
次のようにします。

[FIG(steps)[
= [14] [VAR[文脈]]が[[環境設定群オブジェクト]]で、
[VAR[文脈]]の[F[大域オブジェクト]]が [CODE(DOMi)@en[WorkerGlobalScope]] で、
[VAR[文脈]]の[F[大域オブジェクト]]の[F[閉じ中]]が[[真]]なら、
== [68] ここで停止します。 [SRC[>>10]]
= [39] [VAR[タスク]]を、
新しい[[タスク]]に設定します。
[FIG(list members)[ [40] [[タスク]]

: [F[手順群]] : [VAR[手順群]] 
[SRC[>>1]]
: [F[源][タスク源]] : [VAR[源]] 
[SRC[>>1]]
: [F[文書][タスク]] : [VAR[文書]]
[SRC[>>1]]
: [F[[[triggered by user activation]] その他のフラグ群]] :
[VAR[イベントループ]]の[F[現在走っているタスク]]が [CODE[null]] でなければ、
[VAR[イベントループ]]の[F[現在走っているタスク]]の
[F[[[triggered by user activation]] その他のフラグ群]]
: [F[fetch]] : [VAR[fetch]]
: [F[順序]] : [VAR[イベントループ]]内で[[タスクをキューに追加]]の実行順序を表す値
: [F[捨てる処理]] : [VAR[捨てる処理]]

]FIG]
= [13] [VAR[タスクキュー]]を、
[VAR[イベントループ]]の[F[タスクキュー群]]の[[タスクキュー]]のうち[VAR[源]]に関連付けられものに設定します。
[SRC[>>1]]
= [41] [VAR[タスクキュー]]に、
[VAR[タスク]]を[[末尾に追加]]します。
[SRC[>>1]]
]FIG]


[42] 
[DFN[[RUBYB[タスクを要素キューに[RUBY[追][つい]][RUBY[加][か]]]@en[queue an element task]]]]する処理は、
[[タスク源]][VAR[源]]、
[[要素]][VAR[要素]]、
[[手順群]][VAR[手順群]]について、
次のようにします。
[SRC[>>1]]

[FIG(steps)[
=
[125] 
[VAR[文書]]を、
[VAR[要素]]の[F[節点文書]]に設定します。
=
[126] 
[VAR[イベントループ]]を、
[VAR[要素]]の[F[節点文書]]の[F[関連realm]]の[F[agent]]の[F[イベントループ]]に設定します。
=
[127] 
[VAR[源]]、
[VAR[イベントループ]]、
[VAR[文書]]、
[VAR[手順群]]について、
[[タスクをキューに追加]]します。
]FIG]


[35] [[タスクをキューに追加]]や[[タスクを要素キューに追加]]する操作は、
色々な処理から呼び出されます。
[[Webプラットフォーム]]の[[アルゴリズム]]の基本的な操作の1つです。

[92] 移動の項も参照。

[105] 
[[マイクロタスクをキューに入れる]]は、
名前が似ていますが別の処理です。

-*-*-

[106] 
[DFN[[RUBYB[暗示イベントループ][implied event loop]]]]は、
[[タスクをキューに追加]]や[[マイクロタスクをキューに追加]]する処理を呼び出すアルゴリズムから決まる[[イベントループ]]です。
[SRC[>>1]]
[[仕様書]]は多くの箇所で[[イベントループ]]を明示せず、
[[暗示イベントループ]]に頼る形としています。
(歴史的理由ですが、煩雑さを避けるためもあるのでしょう。)

[107] 
ほとんどの場合は関係する[[エージェント]]が1つだけで、
したがって[[イベントループ]]も1つに定まるので曖昧ではないのですが、
[[エージェント]]間の通信に関する場合は明示しなければ[MUST[ならない]]とされています。
[SRC[>>1]]

[108] 
[VAR[イベントループ]]と[VAR[文脈]]の[DFN[[RUBYB[暗示文書][implied document]]]]は、
次のものです。
[SRC[>>1]]

[FIG(steps)[
= [109] 
[VAR[イベントループ]]が [[window event loop]] で''ない''場合、
== [110] 
[CODE[null]] を返します。
= [111] 
それ以外で、[VAR[文脈]]が[[要素]]の場合、
== [112] 
[VAR[文脈]]の[F[節点文書]]を返します。
= [113] 
それ以外で、[VAR[文脈]]が[[閲覧文脈]]の場合、
== [114] 
[VAR[文脈]]の[F[活性文書]]を返します。
= [115] 
それ以外で、
[VAR[文脈]]が[[スクリプト]]の場合、
== [116] 
[VAR[文脈]]の[F[設定群オブジェクト]]の[F[有責文書]]を返します。
= [117] 
それ以外の場合、
== [118] 
... はないとされます。
]FIG]


* 存在

[28] [CODE(DOMi)@en[[[EventSource]]]], [CODE(DOMi)@en[[[MessagePort]]]] の[[ごみ収集]]のタイミングは、
[[タスク]]が[[タスク・キュー]]に残っているかによって決まります。

;; [29] これは[[タスク]]から [CODE(DOMi)@en[[[EventSource]]]], 
[CODE(DOMi)@en[[[MessagePort]]]] へ[[強い参照]]があると解釈できるかもしれません。

;; [30] [[XHR]] は逆に[[ごみ収集]]によって[[タスク]]を破棄します。

[8] [[the [CODE(HTMLe)@en[embed]] element setup steps]] は、
同[[要素]]に関する[[タスク]]が他に追加されている場合、何も実行しません。
(実行中かどうかではなく追加されたかどうかの検査です。)
この検査は自[[タスク]]のみならず、そこから追加された他の[[タスクキュー]]からも行われます。

* 取得

[15] [[タスクキュー]]は [[FIFO]] っぽいもので、基本的には最古のものから取得 (実行)、
削除されます。しかし条件を満たさない[[タスク]]は[[イベントループ]]に無視されることになっていますから、
厳密には [[FIFO]] とは言えません。

[20] [VAR[イベントループ]]について[DFN[タスクキューからタスクを選択]]するには、
次のようにします。

[FIG(steps)[
= [70] [VAR[タスクキュー]]を、
[VAR[イベントループ]]の[F[タスクキュー群]]内の[[タスクキュー]]のうち、
いずれか1つでも[[タスク]]が[F[走らせられる]]ものを、
[[実装依存]]の方法で選択した結果に設定します。
[SRC[>>9]]
-- [72] [F[状態]]が無効ではないもの (>>34) を選びます。
= [66] [VAR[タスクキュー]]が [CODE[null]] の場合、
== [89] [CODE[null]] を返します。
= [91] それ以外の場合、
== [90] [VAR[タスク]]を、
[VAR[タスクキュー]]の[[タスク]]のうち、最初の[F[走らせられる]]ものに設定します。
== [64] [VAR[タスクキュー]]から、[VAR[タスク]]を[[削除][list remove]]します。
== [67] [VAR[タスク]]を返します。

]FIG]

[21] 同じ[[タスクキュー]]の[[タスク]]は、無視 (遅延) されるものを除き、
実行順序が保証されています。異なる[[タスクキュー]]の[[タスク]]同士がどの順序で実行されるかは、
[[実装依存]]です。

[69] この辺の処理は、[[プラットフォーム]]の影響を受けることもあるでしょうし、
あるいは何を優先的に実行するかは[[実装の品質]]の問題であって (>>12)
[[Webブラウザー事業者]]が工夫して競合するべき点でもあるでしょうから、
仕様としてはあまり具体的に規定せず、かなり自由度を持たせているようです。
何をどのような順序で処理するかが[[相互運用性]]にあまり影響しないということもあります。

[EG[
[79] [[WebSocketメッセージ受信]]における[[タスク]]の実行では、
[[タスク]]の実行に必要な [[I/O]] 
処理を待つ間他の[[タスクキュー]]を実行するような効率化が推奨されています。

;; [[WebSocketメッセージ受信]]参照。
]EG]

[HISTORY[
[48] かつては、
[[タスク]]の決定時点ではまだ[[タスクキュー]]から削除せず、
[[イベントループ]]による[[タスク]]の実行後に[[タスクキュー]]から削除すると規定されていた時期もありました。
[[仕様書]]の構成上の違いだけで、観測可能な違いは生じないはずで、
[[Webブラウザー]]は好きな方法で実装できます。
]HISTORY]

[47] 
[[タスク]]は[F[走らせられる]]ときしか選ばれません。
その条件には[F[文書][タスク]]が[F[完全に活性]]か否かが含まれます。
従って、[[履歴]]移動により非表示状態になった[[文書]]の[[タスク]]は、
実行されません。しかし捨てられたわけではないので、再び表示状態に戻れば実行されます。

[34] [[ポートメッセージキュー]]と[[クライアントメッセージキュー]]は、
有効か無効かのいずれかの[F[状態]]を持ちます。
既定値は無効です。

;; [[仕様書]]上は、[[ポートメッセージキュー]]と[[クライアントメッセージキュー]]は有効になってはじめて[[イベントループ]]が[[タスク源]]として使うようになると規定されています。
[SEE[ [[ポートメッセージキュー]]と[[クライアントメッセージキュー]] ]]

-*-*-

[80] [[HTML構文解析器]]の [CODE(HTMLe)@en[script]] [[要素]]の[[終了タグ]]の処理は、
[DFN[[RUBYB[字句化器をブロック]@en[block the tokenizer]]]]する場合があります。これは、
[DFN[[RUBYB[字句化器をブロック解除]@en[unblock the tokenizer]]]]するまでの間、
当該[[字句化器]]を実行することになる[[タスク]]を[[イベントループ]]が実行しないものと説明されています
[SRC[>>78]]。

[71] なぜかこれは[[構文解析器]]の動作の規定で説明されるだけで、
[[イベントループ]]側の[[アルゴリズム]]には組み込まれていません。
そのため[[仕様書]]の意図する正確な動作は不明です。
しかし、[[構文解析器]]自体が正常に動作することや他の挙動との整合性、
実際の [[Webブラウザー]]の動作との一貫性を考慮すると、
[[イベントループ]]が単一の[[タスクキュー]]しか持たない場合であってもそのような[[タスク]]の後に続く一切の[[タスク]]を実行できないとは考えにくく、
[[完全に活性]]でない[[タスク]]と同様、ブロック解除されるまで無効とされると解釈するのが妥当そうです。

[82] なお、このような挙動を引き起こした[[HTML構文解析器]]によってブロックされる、
[[字句化器]]を実行することになる[[タスク]]、というのは、
[[navigate]] によって実行される [[fetch]] の [[process response]] や
[[process response end-of-body]] の処理を行う[[ネットワークタスク源]]の[[タスク]]です。

[81] ということは、字句化器をブロックするとは、
([F[タスク源]] = [[ネットワークタスク源]], [F[文書]] = [[HTML構文解析器]]の[F[文書]],
[F[fetch]] = その[[構文解析器][HTML構文解析器]]と対になる [[fetch]])
の[[タスクキュー部分リスト]]の[F[状態]]を[[無効]]に設定する、と言い換えられることになります。

* 削除

[22] [[タスク]]は実行される際に[[キュー]]から削除されますが、それ以外にも削除されることがあります。
[FIG(list)[
- [23] [VAR[イベントループ]]について[DFN[[VAR[文書]]のタスクを削除]]:
特定の [CODE(DOMi)@en[[[Document]]]] に関連付けられた[[タスク]]がすべて削除されることがあります。
-- 
[HISTORY[
[CODE[document.open]]
]HISTORY]
-- [[discard a [CODE(DOMi)@en[Document]]]]
- [24] 特定の[[タスク源]]の[[タスク]]がすべて削除されることがあります。
-- [[media element load algorithm]]
-- [CODE(DOMi)@en[[[FileReader]]]] の [CODE(DOMm)@en[[[abort]]]]
-- [CODE(DOMi)@en[[[FileSaver]]]] の [CODE(DOMm)@en[[[abort]]]]
- [27] 特定の[[文書族]]・[[タスク源]]の[[タスク]]がすべて削除されることがあります。
-- [[URLおよび履歴更新手順群]] 
-- [[セッション履歴エントリーの挿入]]
-- [[素片識別子へのnavigate]]
- [26] 特定のものに関する [[fetch]] [[算法]]が生成した[[タスク]]がすべて削除されることがあります。
-- [[update the image data]]
-- [[媒体要素]]
-- [[text track]]
-- [[abort a document]]
-- [[XHR]] の[[ごみ収集]]
- [25] すべての[[タスク]]が削除されることがあります。
-- [CODE(DOMi)@en[[[WorkerGlobalScope]]]] の [CODE(DOMm)@en[[[close]]]]
-- [[kill a worker]]
- [33] 特定の[[タスク]]が削除されることがあります。
-- [[planned navigation]]
]FIG]

* 移動

** ポートメッセージキュー

[17] [[ポートメッセージキュー]]においては、
[[タスク]]が他の[[ポートメッセージキュー]]へと移動されることがあります。
[[タスクキュー部分リスト]]内のすべての[[タスク]]を削除し、
他の[[ポートメッセージキュー]]に改めて追加するものと解することができます。

;; [[ポートメッセージキュー]]参照。

[36] [[ポートメッセージキュー]]の操作
([CODE(DOMm)@en[postMessage]] や [F(ss)[Transfer]]) で[[タスク]]が[[ポートメッセージキュー]]に追加されることがあります。
[[仕様書]]上は[[タスクをキューに追加]]を使わずに規定されていますが、
[[ポートメッセージキュー]]が[[タスクキュー部分リスト]]であると考えれば、
[[タスクをキューに追加]]する操作で記述できます。

[73] [DFN[ポート出荷に伴うタスク移動]]:
[[ポートメッセージキュー]]の[[タスク]]は、[CODE(DOMi)@en[MessagePort]]
の[F[既に出荷済み]]フラグが[[偽]]である間、
[[未出荷済みポートメッセージキュー]]に属するものとみなされ、
[[ポートメッセージキュー]]としての処理は停止されると規定されています。
これは (色々な実装方法がありそうですが) 
[[未出荷済みポートメッセージキュー]]を収容する[[タスクキュー]]から[[ポートメッセージキュー]]に相当する[[タスクキュー部分リスト]]を削除し、
[[ポートメッセージキュー]]が本来収容されるべき[[タスクキュー]]に追加する操作と解することができます。
この操作では[[タスク]]自体は削除と移動されるわけではなく、
[[タスクキュー]]上の[[タスク]]の[F[順序]]が維持される必要があります。

** サービスワーカー

[93] [[サービスワーカーを走らせる]]処理、
[[サービスワーカーを終端させる]]処理で、
[[イベントループ]]と[[サービスワーカー登録]]との間で[[タスク]]が移動されることがあります。

[77] [[handle fetch]] の[DFN[タスクが捨てられる]]時は、
[[タスク]]の[F[捨てる処理]]が実行されます。

* イベント順との関係

[55] [[DOM3イベント]]は[[イベント]]同士の関係を[[イベント順]]により規定しています。
[[DOM3イベント]]は[[イベント・ループ]]や[[タスク]]という概念を使っておらず、
この[[イベント順]]は適宜[[タスク源]]として使うことによって[[イベント・ループ]]と互換性がある形で実装できる、
としています。

[REFS[
- [56] [CITE@en-US[Document Object Model (DOM) Level 3 Events Specification]] ([TIME[2012-03-21 00:00:37 +09:00]] 版) <http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#event-order-and-loops>
]REFS]

;; [57] 具体的にどう対応付けるのかは説明を読んでもあんまりよくわかりません。 [[HTML]]
は[[マウス]]も[[鍵盤]]も同じ[[利用者対話タスク源]]で扱っていますが、
[[DOM3イベント]]は独立してるからそれぞれ別の[[タスク源]]だ、とか言っていますし、
[[焦点]]の変更など独立した操作がそれぞれ[[タスク源]]だ、とか訳のわからないことも言ってます。

* ごみ収集との関係

[74] [[ごみ収集]]、[[ポートメッセージキュー]]参照。

* 歴史

[REFS[
- [6] [CITE@en[Web Applications 1.0 r2074 Define event loops, task queues, etc; Make 'fetching' use this mechanism (everything will in due course); Fix some cross-references around 'interactive content'.]]
([TIME[2008-08-16 09:52:00 +09:00]] 版)
<https://html5.org/r/2074>
- [60] [CITE[IRC logs: freenode / #whatwg / 20100824]]
([TIME[2010-09-02 21:15:06 +09:00]] 版)
<http://krijnhoetmer.nl/irc-logs/whatwg/20100824>
- [16] [CITE@en[Web Applications 1.0 r7992     Make <form> submission more like reality.]] ([TIME[2013-06-20 06:37:00 +09:00]] 版) <http://html5.org/tools/web-apps-tracker?from=7991&to=7992>
- [19] [CITE@en[Fix #19: Remove majority of "DOM Event Architecture" section · w3c/uievents@6cb42db]]
([TIME[2016-03-08 18:11:43 +09:00]] 版)
<https://github.com/w3c/uievents/commit/6cb42db4054c5502d28c3f53c6ae64da5e475747>
]REFS]



[95] [CITE@en[Clarify realm and task-queuing situation in pipeTo() by domenic · Pull Request #902 · whatwg/streams]]
([TIME[2018-03-10 13:29:59 +09:00]])
<https://github.com/whatwg/streams/pull/902>

[96] [CITE@en[Add self.queueMicrotask()]]
([[domenic]]著, [TIME[2018-08-02 06:28:24 +09:00]])
<https://github.com/whatwg/html/commit/9d7cf125f960e6bb8d9b7c9456595f505f2e9d4b>

[97] [CITE@en[document.open() simplifications, part 1]]
([[TimothyGu]]著, [TIME[2018-08-17 07:20:44 +09:00]])
<https://github.com/whatwg/html/commit/6f769b8089a843066aa19f5991405bf4c84458b3>

[98] [CITE@en[No longer remove tasks for document.open() by annevk · Pull Request #3665 · whatwg/html]]
([TIME[2018-08-23 20:17:54 +09:00]])
<https://github.com/whatwg/html/pull/3665>

[99] [CITE@en[document.open() simplifications: realm creation, unloading, tasks removal by TimothyGu · Pull Request #3918 · whatwg/html]]
([TIME[2018-08-23 20:19:07 +09:00]])
<https://github.com/whatwg/html/pull/3918>

[100] [CITE@en[document.open() simplifications, part 2]]
([[TimothyGu]]著, [TIME[2018-08-21 03:57:31 +09:00]])
<https://github.com/whatwg/html/commit/ae7cf0cc1936c6c309d7279c822dffc3af147851>

[101] [CITE@en[Editorial: rigorize tasks and task queuing]]
([[domenic]], [TIME[2019-05-01 01:36:30 +09:00]], [TIME[2021-03-25T08:52:45.000Z]])
<https://github.com/whatwg/html/commit/f4e29076caad1779336adea40ac2125d6d1c9496>

[119] [CITE@en[Script event-loop: ignoring tasks for documents that are not fully active · Issue #4242 · whatwg/html]]
([TIME[2021-03-25T11:52:45.000Z]])
<https://github.com/whatwg/html/issues/4242>

[120] [CITE@en[Editorial: rigorize tasks and task queuing by domenic · Pull Request #4465 · whatwg/html]]
([TIME[2021-03-25T11:54:07.000Z]])
<https://github.com/whatwg/html/pull/4465>

[121] [CITE@en[Editorial: remove now-redundant removal of event loop task]]
([[domenic]], [TIME[2019-09-13 14:26:06 +09:00]], [TIME[2021-04-12T05:25:18.000Z]])
<https://github.com/whatwg/html/commit/edcf2eff7570fd142188e45350eb9c69bad9b9fc>

[122] [CITE@en[Editorial: remove now-redundant removal of event loop task by domenic · Pull Request #4897 · whatwg/html]]
([TIME[2021-04-12T05:26:15.000Z]])
<https://github.com/whatwg/html/pull/4897>

[123] [CITE@en[Duplicated removal from queue in the Event Processing Model · Issue #4888 · whatwg/html]]
([TIME[2021-04-12T05:26:47.000Z]])
<https://github.com/whatwg/html/issues/4888>

[124] [CITE@en[Add "queue an element task" algorithm]]
([[dtapuska]], [TIME[2019-12-06 05:15:14 +09:00]], [TIME[2022-01-27T09:31:52.000Z]])
<https://github.com/whatwg/html/commit/a9e1d2ad5a7569010c685b271965ae4a3a34a64b>

[128] [CITE@en[Add the ability to queue an element task. by dtapuska · Pull Request #5072 · whatwg/html]]
([TIME[2022-01-27T09:53:48.000Z]])
<https://github.com/whatwg/html/pull/5072>