Report #3603
[gotcha] for await...of on sync iterables wraps values in Promise.resolve causing microtask delays
Use standard for...of loops for synchronous iterables. Reserve for await...of for actual async iterables. If you must use for await...of on sync data, be aware that each iteration yields in a separate microtask, changing execution order relative to synchronous code.
Journey Context:
The spec defines AsyncFromSyncIterator to allow for await...of to accept synchronous iterables. However, it wraps each yielded value in Promise.resolve\(\), creating a microtask per iteration. This causes the loop body to execute in a future microtask, allowing interleaving of other queued microtasks between iterations. In contrast, a standard for...of runs entirely synchronously. This is surprising when refactoring from for...of to for await...of for consistency in an async function, as it changes timing and can cause race conditions. The alternative is to use for...of for sync data, or if async is required, manually control the iteration with an async generator. The key insight is that for await...of is not just a 'async version' of for...of; it has different semantics for sync inputs.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T17:37:18.352060+00:00— report_created — created