Skip to content

Add tests for iterator close semantics of Array.fromAsync - #5095

Open
littledivy wants to merge 1 commit into
tc39:mainfrom
littledivy:fromasync-iterator-close-tests
Open

Add tests for iterator close semantics of Array.fromAsync#5095
littledivy wants to merge 1 commit into
tc39:mainfrom
littledivy:fromasync-iterator-close-tests

Conversation

@littledivy

@littledivy littledivy commented Jul 24, 2026

Copy link
Copy Markdown

The existing Array.fromAsync tests cover that an abrupt mapper completion closes the iterator (mapfn-*-throws-close-*-iterator.js), but not the surrounding close semantics:

  • does-not-close-exhausted-async-iterator.js / does-not-close-exhausted-sync-iterator.js: a normal completion (done: true) must not call return(); iteration ends with a return completion, never AsyncIteratorClose.
  • mapfn-throws-close-async-iterator-awaited.js: the close is awaited, so the promise from return() settles before the promise returned by Array.fromAsync is rejected (AsyncIteratorClose step 5.d).
  • mapfn-throws-close-rejection-not-masked.js: when both the mapper and return() fail, the promise rejects with the mapper's error (AsyncIteratorClose step 6 returns the original completion).

These distinguish implementations today: quickjs-ng closed exhausted iterators without awaiting the result (fix in quickjs-ng/quickjs#1596, which prompted these tests), and V8 (Node 24.14) never settles the returned promise at all when return() throws or rejects during an abrupt close, so the last test currently hangs there.

@littledivy
littledivy requested a review from a team as a code owner July 24, 2026 14:02
@littledivy littledivy changed the title Add Array.fromAsync iterator close semantics tests Add tests for iterator close semantics of Array.fromAsync Jul 24, 2026
@littledivy
littledivy force-pushed the fromasync-iterator-close-tests branch from 7e94308 to 0de3c0a Compare July 24, 2026 14:12
The existing fromAsync tests cover that an abrupt mapper completion
closes the iterator, but not the surrounding close semantics:

- a normal completion (done: true) must not call return()
- the close is awaited: the promise from return() settles before the
  promise returned by Array.fromAsync is rejected
- when both the mapper and return() fail, the promise rejects with the
  mapper's error (AsyncIteratorClose returns the original completion)

These distinguish implementations today: quickjs-ng closed exhausted
iterators without awaiting, and V8 never settles the returned promise
when return() throws or rejects during an abrupt close.
@littledivy

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants