fix(ext/web): fire FileReader progress events as tasks#34763
Conversation
The read operation in FileReader fired its progress events (loadstart,
progress, load/error, loadend) via queueMicrotask. The File API spec
requires these to be dispatched by "queue a task". The distinction is
observable: a single read fires several events in sequence, and consumers
(notably the WPT EventWatcher) rely on the microtask queue draining
between them so a listener can react to one event before the next is
dispatched. Using microtasks collapsed the events into a single turn, so
they arrived back-to-back.
Switch the dispatches to a task (setTimeout) and queue loadend as its own
task so the preceding load/error event can be observed before loadend.
Fixes WPT FileAPI/reading-data-section/filereader_events.any.{html,worker.html}
("events are dispatched in the correct order for an empty blob" and
"... for a non-empty blob").
|
@crowlKats ready for review The WPT job is green — |
|
@crowlbot shouldnt we have a proper implementation of a task rather than settimeout? furthern investigate this spec language. |
|
Thanks for the review — I looked into both points. Spec language. The read operation says "queue a task" for each of Why Among the primitives we expose,
|
What
FileReader's read operation fired its progress events —loadstart,progress,load/error,loadend— usingqueueMicrotask. TheFile API read operation
specifies that each of these is dispatched by "queue a task".
This switches those dispatches to a task (
setTimeout) and queuesloadendas its own task so the precedingload/errorevent can beobserved before
loadend.Why
The task-vs-microtask distinction is observable. A single read fires
several events in sequence, and consumers rely on the microtask queue
draining between them — so a listener (or an
await) can react to oneevent before the next is dispatched. The WPT
EventWatcheris exactlysuch a consumer: it re-arms for the next event in a microtask after the
previous one resolves. With
queueMicrotask, the events collapsed into asingle turn and arrived back-to-back, so
EventWatcherreported"Not expecting event, but got <event>".
The existing code already carried
TODOs noting thatqueueMicrotaskwaswrong and should be "queue a task".
Spec
File API §read operation,
steps that queue tasks to fire
loadstart,progress,load,error,and
loadend.WPT subtests now passing
FileAPI/reading-data-section/filereader_events.any.htmland.any.worker.html:tests/wpt/runner/expectations/FileAPI.jsonis flipped fromfalsetotruefor both files.Root cause
FileReader#readOperationinext/web/10_filereader.jsdispatched allprogress events via
queueMicrotaskinstead of as tasks, and firedload+loadend(anderror+loadend) within a single task.