Skip to content

Await async iterator return() when a for-await loop breaks#1580

Merged
saghul merged 1 commit into
quickjs-ng:masterfrom
littledivy:fix/await-async-iterator-close
Jul 17, 2026
Merged

Await async iterator return() when a for-await loop breaks#1580
saghul merged 1 commit into
quickjs-ng:masterfrom
littledivy:fix/await-async-iterator-close

Conversation

@littledivy

Copy link
Copy Markdown
Contributor

When a for await loop is exited via break, the async iterator's return() method is called but its result is not awaited. Per spec, AsyncIteratorClose performs Await(Call(return, iterator)), so code after the loop must not run until that promise settles. Only async generators awaited the close; a plain async function used the synchronous close path.

const it = { [Symbol.asyncIterator]() { let i = 0; return {
  next() { return Promise.resolve({ value: i++, done: false }); },
  return() { log.push("return"); return Promise.resolve().then(() => log.push("resolved")); },
}; } };
for await (const x of it) break;
log.push("after");
step order before after
return called yes yes
return() promise awaited no yes
log return, after return, resolved, after

The break/loop close now routes async iterators through a shared helper that calls return() and awaits it, and skips the call when the iterator was already closed on normal completion.

Disclaimer: This is an AI-assisted patch from the v8x project.

When a `for await` loop was exited via `break`, the async iterator's
return() method was called but its result was not awaited. Per spec,
AsyncIteratorClose performs Await(Call(return, iterator)), so execution
must not continue until that promise settles. Only async generators
awaited the close; a plain async function used the synchronous
OP_iterator_close path.

The break/loop-close emit now routes async iterators through a shared
emit_iterator_close() helper that calls return() and awaits it, and
skips the call when the iterator has already been closed on normal
completion (the slot is undefined), matching the sync for-of behavior.
@saghul
saghul merged commit d5a59c3 into quickjs-ng:master Jul 17, 2026
128 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants