[whatwg/webidl] Update ongoing promise in async iterator return() method (PR #1387)

@yuki3 found [an interesting edge case](https://chromium-review.googlesource.com/c/chromium/src/+/5263418/6#message-d786cceaee26217e9a67d9201f5e10d1c0c4a34e) related to async iterators.

In Firefox and Node.js (where async iteration on `ReadableStream` is already supported), when you run this snippet:
```js
const readable = new ReadableStream({
  start(c) {
    c.enqueue("a");
    c.enqueue("b");
  },
  cancel() {
    console.warn("cancelled");
  }
});

const it = readable.values();
const p1 = it.next().then(x => console.log("next 1 resolved with", x));
const p2 = it.return().then(x => console.log("return resolved with", x));
const p3 = it.next().then(x => console.log("next 2 resolved with", x));
```
you get:
```
next 1 resolved with { value: 'a', done: false }
cancelled
next 2 resolved with { done: true, value: undefined }
return resolved with { done: true, value: undefined }
```

This is quite surprising: the second `next()` call resolves *before* the `return()` call, even though it was called *after* `return()`. Intuitively, we would expect all async iterator calls to get queued. Indeed, if you do the same thing with an async generator:
```js
async function* test() {
  try {
    yield "a";
    yield "b";
  } finally {
    console.warn("cancelled");
  }
}

const it = test();
const p1 = it.next().then(x => console.log("next 1 resolved with", x));
const p2 = it.return().then(x => console.log("return resolved with", x));
const p3 = it.next().then(x => console.log("next 2 resolved with", x));
```
you get the results in the same order as they were called:
```
next 1 resolved with { value: 'a', done: false }
cancelled
return resolved with { value: undefined, done: true }
next 2 resolved with { value: undefined, done: true }
```

Yuki and I believe this to be a bug in the Web IDL specification. More precisely, the `return()` method should update the ongoing promise, such that future calls to `next()` and `return()` are properly chained. This aligns more closely with the behavior of async generators.

---

- [ ] At least two implementers are interested (and none opposed):
   * …
   * …
- [ ] [Tests](https://github.com/web-platform-tests/wpt) are written and can be reviewed and commented upon at:
   * … <!-- If these tests are tentative, link a PR to make them non-tentative. -->
- [ ] [Implementation bugs](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) are filed:
   * Chromium: …
   * Gecko: …
   * WebKit: …
   * Deno: …
   * Node.js: …
   * webidl2.js: …
   * widlparser: …
- [ ] [MDN issue](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) is filed: …
- [ ] The top of this comment includes a [clear commit message](https://github.com/whatwg/meta/blob/main/COMMITTING.md) to use. <!-- If you created this PR from a single commit, Github copied its message. Otherwise, you need to add a commit message yourself. -->

(See [WHATWG Working Mode: Changes](https://whatwg.org/working-mode#changes) for more details.)

You can view, comment on, or merge this pull request online at:

  https://github.com/whatwg/webidl/pull/1387

-- Commit Summary --

  * Update ongoing promise in async iterator return() method

-- File Changes --

    M index.bs (12)

-- Patch Links --

https://github.com/whatwg/webidl/pull/1387.patch
https://github.com/whatwg/webidl/pull/1387.diff

-- 
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/webidl/pull/1387
You are receiving this because you are subscribed to this thread.

Message ID: <whatwg/webidl/pull/1387@github.com>

Received on Wednesday, 7 February 2024 23:13:44 UTC