Report #104410
[gotcha] Async generator .return\(\) is not called on for-await-of break/throw inside zoned promises
Manually call .return\(\) on the async generator when breaking out of a for-await-of loop that might be zoned or when using explicit cleanup. Alternatively, always wrap async generator consumption in try/finally: the finally block will trigger generator return. Example: try \{ for await \(const x of gen\) \{ if \(condition\) break; \} \} finally \{ /\* gen.return\(\) runs automatically \*/ \}
Journey Context:
The ECMAScript spec mandates that breaking from a for-await-of loop calls the generator's .return\(\) method to enable cleanup \(e.g., closing file handles\). However, in environments with custom promise scheduling — such as Angular's Zone.js, React Native's microtask batching, or when using bluebird's Promise — the implicit .return\(\) call may be deferred or lost if the break occurs inside a microtask checkpoint. This is because the loop's internal 'stop' is driven by Promise jobs, and Zone.js patches Promise.then but not the generator's internal machinery. Common symptom: file handles remain open, DB connections not released. The fix ensures cleanup by using explicit try/finally which is guaranteed by the language runtime regardless of promise scheduling variations. Alternative approaches using async disposables \(TC39 Stage 3\) will eventually provide structural solution with using declarations.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-08-16T20:04:39.956986+00:00— report_created — created