/
258.txt
285 lines (227 loc) · 19.8 KB
/
258.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
[35] [DFN[[RUBYB[[[マイクロタスク]]]@en[microtask]]]]は、 [[Webブラウザー]]における処理の単位で、
[[変異観測器]]や[[表]]の[[整列]]などの処理で用いられています。
* 仕様書
[REFS[
- [49] '''[CITE@en-US-x-hixie[HTML Standard]] ([TIME[2014-04-03 03:44:44 +09:00]] 版) <http://www.whatwg.org/specs/web-apps/current-work/#microtask>'''
- [7] [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/#perform-a-microtask-checkpoint>
]REFS]
* マイクロタスク
[50] [[マイクロタスク]]は、最初に[[タスクキュー]]ではなく[[マイクロタスクキュー]]に入れられた[[タスク]]です。
[[マイクロタスク]]には[[ぼっちコールバックマイクロタスク]]と[[複合マイクロタスク]]の2種類があります。 [SRC[>>49]]
[51] [[マイクロタスク]]が通常の[[タスク]]に比べて「マイクロ」であるのは、
[[タスク]]が[[イベントループ]]の全体によって順次処理されていくのに対し、
[[マイクロタスク]]のほとんどがその[[イベントループ]]の一度の繰り返しの内で順次実行されることを指しています。
[[マイクロタスク]]自体も[[タスク]]の一種なのであって、
[[マイクロタスク]]によって[[タスク]]が構成されるような階層構造には''ありません''。
[42] [[マイクロタスク]]には、次のものがあります。
[FIG(list)[
- [[ぼっちコールバックマイクロタスク]]
-- [CODE(HTMLa)@en[[[sortable]]]] な[[表]]の[[整列]] [SRC[[[HTML Standard]]]]
-- [[安定状態の提供]] [SRC[[[HTML Standard]]]]
-- [[update the image data]] [SRC[[[HTML Standard]]]]
-- [CODE(DOMa)@en[[[timeout]]]] [SRC[[[XHR]]]]
- [[複合マイクロタスク]]
-- [[変異観測器]]の[[コールバック]]の呼び出し [SRC[[[DOM Standard]]]]
@@
- [[カスタム要素]]の[[コールバック]]の呼び出し [SRC[[[Custom Elements]]]]
- [[Promise]] の[[コールバック]]の呼び出し [SRC[[[ECMAScript]]]]
[HISTORY[
- [CODE(JS)@en[[[Object.observe]]]] の[[コールバック]]の呼び出し [SRC[[[ECMAScript]]]]
]HISTORY]
]FIG]
[38] [[拒絶された約束について通知]]は、[[マイクロタスク]]ではありませんが、
[[マイクロタスク]]が実行されるタイミングで[[マイクロタスク]]の後に実行され、
実質的に特別な[[マイクロタスク]]となっています。
** ぼっちコールバックマイクロタスク
[61] [DFN[[RUBYB[[[ぼっちコールバックマイクロタスク]]]@en[solitary callback microtask]]]]は、
それ自体が実行時の最小単位の[[タスク]]となるような[[マイクロタスク]]です。
** 複合マイクロタスク
[62] [DFN[[RUBYB[[[複合マイクロタスク]]]@en[compound microtask]]]]は、
実行時に最小単位の[[タスク]]複数個に分割され得る[[マイクロタスク]]です。
[78] [[複合マイクロタスク]]の一部として実行される[[タスク]]のことを、
[DFN[[RUBYB[[[複合マイクロタスク部分タスク]]]@en[compound microtask subtask]]]]といいます。
[EG[
[77] 例えば [[mutation observer]] の[[マイクロタスク]]は、複数の [CODE(DOMi)@en[[[MutationObserver]]]]
[[コールバック]]を呼び出す可能性があり、
それぞれが[[複合マイクロタスク部分タスク]]であるような1つの[[複合マイクロタスク]]として定義されています。
]EG]
[66] [[複合マイクロタスク]]は、[[イベントループのスピン]]時の挙動を正しく扱えるように注意する必要があります。
そのために[[複合マイクロタスク部分タスクを実行する]]手順 (>>67) が用意されていて、
[[複合マイクロタスク]]を定義する仕様書はこれを参照することが期待されています。
* マイクロタスクキュー
[53] [[イベントループ]]は[DFN[[RUBYB[[[マイクロタスクキュー]]]@en[microtask queue]]]]を ([[タスクキュー]]とは別に)
持ちます。[DFN[[RUBYB[[[マイクロタスクをキューに入れる]]]@en[queue a microtask]]]]とは、
[[マイクロタスク]]を自[[イベントループ]]の[[マイクロタスクキュー]]の末尾に追加することをいいます。
[SRC[>>49]]
* マイクロタスクタスク源
[54] [[マイクロタスク]]の[[タスク源]]は[DFN[[RUBYB[[[マイクロタスクタスク源]]]@en[microtask task source]]]]となります。
[SRC[>>49]] [[マイクロタスクキュー]]には[[タスク源]]は関係してこないので、ほとんどの[[マイクロタスク]]は[[タスク源]]と無関係ですが、
[[マイクロタスク]]が[[タスクキュー]]に移されると[[タスク源]]が関係してきます。
* マイクロタスクの実行
[15] [[マイクロタスクチェックポイントを行う]]のは次の場面です。
[FIG(list)[
- [16] [[イベントループ]]
- [83] [[イベントループのスピン]]
- [17] [[clean up after running a callback]] ([[コード入口点に飛ぶ]]手順から呼び出される)
- [18] [[HTML]] [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[終了タグ]]の[[構文解析]]時 ([[スクリプト]]実行の前)
;; [19] [[SVG]] [CODE(XMLe)@en[[[script]]]] [[要素]]でも同様に呼び出されるものと推察されますが、
現時点で [[SVG]] [CODE(XMLe)@en[[[script]]]] [[要素]]の処理モデルを詳細に規定した仕様がありません。
]FIG]
[82] つまり[[マイクロタスク]]は、[[スクリプト]]や[[タスク]]の前後に実行されます。
複数の[[マイクロタスク]]があれば、それらをすべて実行してから次の[[タスク]]へと進みます。
* マイクロタスクチェックポイント
[12] [VAR[[[イベントループ]]]]について[DFN[[RUBYB[[[マイクロタスクチェックポイントを行う]]]@en[perform a microtask checkpoint]]]]際には次のようにし[['''なければなりません''']] [SRC[>>7]]。
[FIG(steps)[
= [8] [VAR[[[イベントループ]]]]の[F[[[マイクロタスクチェックポイントを行っている]]フラグ]]が[[真]]なら、ここで停止します。
= [9] [VAR[[[イベントループ]]]]の[F[[[マイクロタスクチェックポイントを行っている]]フラグ]]を[[真]]にします。
= [55] [VAR[[[イベントループ]]]]の[F[[[マイクロタスクキュー]]]]が空でない間、繰り返し、
次の通り実行します。
== [56] [VAR[タスク]]を、[VAR[[[イベントループ]]]]の[F[[[マイクロタスクキュー]]]]の最古の[[マイクロタスク]]に設定します。
== [63] [VAR[[[イベントループ]]]]の[F[[[現在走っているタスク]]]]を、[VAR[タスク]]に設定します。
== [64] [VAR[タスク]]を実行します。
== [65] [VAR[[[イベントループ]]]]の[F[[[現在走っているタスク]]]]を、 [[null]] に設定します。
== [58] [VAR[[[イベントループ]]]]の[F[[[マイクロタスクキュー]]]]から[VAR[タスク]]を削除します。
= [32] [VAR[[[イベントループ]]]]が[F[[[有責イベントループ]]]]である各[[環境設定群オブジェクト]]について、
== [36] その[[環境設定群オブジェクト]]の[[拒絶された約束について通知]]します。
= [13] [VAR[[[イベントループ]]]]の[F[[[マイクロタスクチェックポイントを行っている]]フラグ]]を[[偽]]にします。
]FIG]
[34] [[イベントループ]]は[F[[DFN[[RUBYB[[[マイクロタスクチェックポイントを行っている]]]@en[performing a microtask checkpoint]]]]フラグ]]を持っており、初期値は[[偽]]です。 [SRC[>>7]]
;; [11] [[マイクロタスク]]によって[[コールバック]]の[[スクリプト]]が呼び出されたりするわけですが、
その際 [[jump to a code entry-point]] [[アルゴリズム]]が呼ばれ、
その中で再度[[マイクロタスクチェックポイント]]が呼ばれることになるので、
[[マイクロタスクチェックポイントを行っている]]フラグでチェックして再実行しないようにしています。
* 複合マイクロタスク部分タスクの実行
[67] 指定された手順について[DFN[[RUBYB[[[複合マイクロタスク部分タスクを実行する]]]@en[execute a compound microtask subtask]]]]とは次のような手順をいいます [SRC[>>7]]。
[FIG(steps)[
= [68] [VAR@en[parent]] を[[現在走っているタスク]]とします。
== [69] これは本手順を呼び出している[[複合マイクロタスク]]となります。
= [70] [VAR@en[subtask]] を指定された手順を実行する[[タスク]]とします。
これが[[複合マイクロタスク部分タスク]]です。
[[タスク源]]は[[マイクロタスクタスク源]]とします。
= [71] [[現在走っているタスク]]を [VAR@en[subtask]] とします。
= [72] [VAR@en[subtask]] を実行します。
= [73] [[現在走っているタスク]]を [VAR@en[parent]] とします。
]FIG]
;; [79] この手順はすなわち、「ある手順をその場で[[タスク]]として実行する」ということになります。
[[複合マイクロタスク]]はそれ自体の手順の中で、[[複合マイクロタスク部分タスク]]として実行したい部分を >>67
の手順で“包んで”実行することになります。これは[[スピン]]の挙動を定義するためであり、
ただの[[ぼっちコールバックタスク]]と[[複合マイクロタスク]]が異なるのは[[スピン]]に対する挙動だけです。
[[スピン]]は実行中の[[タスク]]を終了させ、続きの実行を後回しにします。この後で実行する単位が、
>>67 によって当該[[複合マイクロタスク部分タスク]]だけに限定されます。 [[mutation observer]]
の場合だと、当該 [CODE(DOMi)@en[[[MutationObserver]]]] だけが中断され、他の [CODE(DOMi)@en[[[MutationObserver]]]]
があればそれらは即座に実行されます。
* 歴史
[37] [[マイクロタスク]]は[[変異観測器]]のための仕組みとして [[HTML Standard]] に導入されました。
[REFS[
- [33] [CITE@en[DOM Mutation Events Replacement: When to deliver mutations]] ([[Rafael Weinstein]] 著, [TIME[2011-08-11 09:44:32 +09:00]] 版) <http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0780.html>
- [1] [CITE[IRC logs: freenode / #whatwg / 20120228]]
( ([TIME[2012-03-08 00:01:17 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20120228>
- [2] [CITE@en[Re: ''''''[''''''dom'''''']'''''' mutation observers and HTML]]
( ([[Olli Pettay]] 著, [TIME[2012-02-18 00:51:23 +09:00]] 版))
<http://lists.w3.org/Archives/Public/www-dom/2012JanMar/0066.html>
- [3] [CITE[IRC logs: freenode / #whatwg / 20120320]]
( ([TIME[2012-03-29 23:32:57 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20120320>
- [14] [CITE[Bug 17988 – The term microtask should be defined]]
( ([TIME[2012-07-21 17:51:05 +09:00]] 版))
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=17988>
- [21] [CITE@en[Web Applications 1.0 r7597 New feature: sorting tables. The actual sort algorithm isn't done yet, but this should be a good start for first draft reviewers.]] ([TIME[2012-12-27 08:58:00 +09:00]] 版) <http://html5.org/tools/web-apps-tracker?from=7596&to=7597>
- [20] [CITE@en[Web Applications 1.0 r7484 The parser should have mutation observers.]] ([TIME[2012-10-24 07:24:00 +09:00]] 版) <http://html5.org/tools/web-apps-tracker?from=7483&to=7484>
-[24] [CITE[IRC logs: freenode / #whatwg / 20130528]]
( ([TIME[2013-05-29 23:52:26 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20130528#l-1044>
-[25] [CITE@en[Bug 22185 – Microtask checkpoint wording is wrong -- and needs abstracting]]
( ([TIME[2013-06-09 01:40:24 +09:00]] 版))
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=22185>
-[26] [CITE@en[Web Applications 1.0 r7950 Bring the 'microtask checkpoint' invocation at the end of scripts more into line with implementations, and unrelated editorial fixes.]]
( ([TIME[2013-06-11 05:52:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=7949&to=7950>
-[27] [CITE@en[Bug 22296 – Microtask and promises]]
( ([TIME[2013-09-13 07:31:35 +09:00]] 版))
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=22296>
-[29] [CITE[IRC logs: freenode / #whatwg / 20131107]]
( ([TIME[2013-11-09 12:27:06 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20131107#l-600>
-[40] [CITE@en[Web Applications 1.0 r8265 Provide integration hook for Custom Elements spec.]] ([TIME[2013-11-12 07:10:00 +09:00]] 版) <http://html5.org/tools/web-apps-tracker?from=8264&to=8265>
]REFS]
[39] [CODE(URI)@en[[[blob:]]]] についても[[マイクロタスクチェックポイント]]での処理が検討されましたが、
[[global script clean-up jobs list]] という新しい仕組みになりました。
[REFS[
- [23] [CITE@en[Bug 19554 – Needed: An Algorithmic "Hook" For Culling URL.objectURLs with autoRevoke=true]]
( ([TIME[2013-05-30 08:45:57 +09:00]] 版))
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=19554>
]REFS]
[41] ここまで仕様書上[[マイクロタスク]]と呼ばれるものはなく、
[[マイクロタスクチェックポイント]]の一連の処理として定義されていました (>>12)。
[52] しかし >>48 によって[[タスク]]の一種として[[マイクロタスク]]が定義されるようになりました。
[[マイクロタスクキュー]]が導入され、[[マイクロタスク]]が後に通常の[[タスクキュー]]によって処理され得る単位となったのもこの時です。
それに加えて >>60 により、[[複合マイクロタスク]]が導入され、
[[マイクロタスク]]の一部分が[[複合マイクロタスク部分タスク]]として実行されるケースが生じました。
[REFS[
- [43] [CITE[IRC logs: freenode / #whatwg / 20140219]]
( ([TIME[2014-02-20 21:02:47 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20140219#l-367>
- [44] [CITE[IRC logs: freenode / #whatwg / 20140220]]
( ([TIME[2014-02-22 00:03:19 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20140220>
- [45] [CITE@en[Web Applications 1.0 r8507 Prevent microtasks from running reentrantly via the parser.]]
( ([TIME[2014-02-22 08:02:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=8506&to=8507>
- [46] [CITE[IRC logs: freenode / #whatwg / 20140303]]
( ([TIME[2014-03-04 20:47:42 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20140303#l-550>
- [47] [CITE[IRC logs: freenode / #whatwg / 20140331]]
( ([TIME[2014-04-02 13:54:03 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20140331#l-653>
- [48] [CITE@en[Web Applications 1.0 r8463 First attempt at speccing the generic microtask queue idea.]]
( ([TIME[2014-02-05 10:00:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=8462&to=8463>
- [60] [CITE@en[Web Applications 1.0 r8510 Lay the groundwork for interruptible microtasks, mutation-observer style.]] ([TIME[2014-02-25 12:53:00 +09:00]] 版) <http://html5.org/tools/web-apps-tracker?from=8509&to=8510>
- [74] [CITE@en[Web Applications 1.0 r8553 Make microtasks work in workers too, since eventually we'll want the JavaScript stuff to hook into this]] ([TIME[2014-03-19 03:12:00 +09:00]] 版) <http://html5.org/tools/web-apps-tracker?from=8552&to=8553>
- [81] [CITE@en[Web Applications 1.0 r8577 Fix prose around the <textarea> value / maxlength issues to be slightly less confusing and ambiguous. Clean up some text around MutationObservers.]] ([TIME[2014-04-24 00:38:00 +09:00]] 版) <http://html5.org/tools/web-apps-tracker?from=8576&to=8577>
- [84] [CITE@en[Web Applications 1.0 r8617 Move table sorting to microtasks.]] ([TIME[2014-05-08 07:52:00 +09:00]] 版) <http://html5.org/tools/web-apps-tracker?from=8616&to=8617>
- [85] [CITE@en[Web Applications 1.0 r8633 Remove the obsolete integration for custom elements from the HTML spec.]] ([TIME[2014-05-15 05:19:00 +09:00]] 版) <http://html5.org/tools/web-apps-tracker?from=8632&to=8633>
- [86] [CITE@en[Web Applications 1.0 r8630 Refactor 'stable states' to be defined in terms of microtasks]] ([TIME[2014-05-14 04:18:00 +09:00]] 版) <http://html5.org/tools/web-apps-tracker?from=8629&to=8630>
]REFS]
[75] >>74 で[[マイクロタスク]]はメインの[[イベントループ]]だけでなく、[[ワーカー]]でも実行可能となりました。
[REFS[
- [4] [CITE@en[Make update the image data run when the document becomes active. · ee68507 · ResponsiveImagesCG/picture-element]] ([TIME[2014-10-23 10:42:01 +09:00]] 版) <https://github.com/ResponsiveImagesCG/picture-element/commit/ee685075cd65f02022d74b7932073fda4102d15f>
- [6] [CITE@en[Fix normative requirements for the timeout attribute (including for sync... · 2677cc2 · whatwg/xhr]] ([TIME[2014-10-23 10:46:18 +09:00]] 版) <https://github.com/whatwg/xhr/commit/2677cc2e0fe79d290437c3ea9ff370a5d795294b>
]REFS]
[5] >>4 で[[安定状態]]を提供するもの以外でも[[アルゴリズム]]の途中からの継続に[[マイクロタスク]]が使われるようになっています。
[10] >>6 で [[XHR]] の [CODE(DOMa)@en[[[timeout]]]] も[[マイクロタスク]]として再定義されました。
* 関連
[80] [[大域スクリプト片付けジョブ]]は[[マイクロタスク]]と似ていて同じようなタイミングで実行されますが、
異なるタイミングで実行されることもあります。
[87] [CITE@en[Re: Indexed DB Transactions vs. Microtasks]]
( ([[Jonas Sicking]] 著, [TIME[2014-06-07 09:51:31 +09:00]] 版))
<http://lists.w3.org/Archives/Public/public-webapps/2014AprJun/0861.html>
[88] [CITE@en[Bug 25714 - ''''''[''''''Custom'''''']'''''': Move microtask processing to compound microtask · ffeeba6 · w3c/webcomponents]]
( ([TIME[2014-11-23 18:29:07 +09:00]] 版))
<https://github.com/w3c/webcomponents/commit/ffeeba6b1a3446ebc183a0ae2b7ee8445e44635d>
[22] [CITE[IRC logs: freenode / #whatwg / 20150120]]
([TIME[2015-01-22 11:39:35 +09:00]] 版)
<http://krijnhoetmer.nl/irc-logs/whatwg/20150120#l-658>
[FIG(quote)[
[FIGCAPTION[
[28] [CITE[IRC logs: freenode / #whatwg / 20150811]]
([TIME[2015-08-12 11:03:34 +09:00]] 版)
<http://krijnhoetmer.nl/irc-logs/whatwg/20150811>
]FIGCAPTION]
>
> # '''['''11:34''']''' <JakeA> Chrome's implementation performs a microtask checkpoint per listener, Firefox doesn't
]FIG]
[FIG(quote)[
[FIGCAPTION[
[30] [CITE[Tasks, microtasks, queues and schedules - JakeArchibald.com]]
([TIME[2015-09-15 11:02:26 +09:00]] 版)
<https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/>
]FIGCAPTION]
> Firefox and Safari are correctly exhausting the microtask queue between click listeners, as shown by the mutation callbacks, but promises appear to be queued differently. This is sort-of excusable given that the link between jobs & microtasks is vague, but I'd still expect them to execute between listener callbacks. Firefox ticket. Safari ticket.
> With Edge we've already seen it queue promises incorrectly, but it also fails to exhaust the microtask queue between click listeners, instead it does so after calling all listeners, which accounts for the single mutate log after both click logs. Bug ticket.
]FIG]
[31] [CITE@en[Add promise rejection tracking events · whatwg/html@61ccc05]]
([TIME[2015-12-03 22:59:10 +09:00]] 版)
<https://github.com/whatwg/html/commit/61ccc05b7437ba947390928f9e526da49550fed0>
[57] [CITE@en[Remove the storage mutex due to lack of implementation · whatwg/html@1b918cf]] ([TIME[2015-12-16 14:38:10 +09:00]] 版) <https://github.com/whatwg/html/commit/1b918cf72fcbba011f83b92ab5d1f483fb1cafa3>