Description
Bug Report
🔎 Search Terms
async
generator
yield
finally
🕗 Version & Regression Information
Version: Version 4.3.5
- This is the behavior in every version I tried (including nightly), and there doesn't seem to be any FAQ entries about this particular topic.
⏯ Playground Link
Playground link with relevant code
💻 Code
async function* generator1() {
try {
yield 1;
} finally {
yield 2;
}
}
async function* generator2() {
yield* generator1();
}
const it = generator2();
(async function () {
console.log(await it.next());
console.log(await it.return());
console.log(await it.next());
}());
🙁 Actual behavior
The output of the above program is:
{ done: false, value: 1 }
{ done: true, value: undefined }
{ done: true, value: undefined }
This behavior can be observed for any compilation target lower than es2018
. For es2018
and above there's no code transformation at all, and so the native implementation of async generators is used upon execution. This suggests that something is wrong with the corresponding polyfill. Indeed, after a closer examination:
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
};
seems to be ignoring the fact that calling it.return()
does not necessarily result in { done: true }
, which is effectively enforced by done: n === "return"
.
What is worth mentioning is the same problem doesn't occur for synchronous generators at all, which indicates that this is specific to how asynchronous generators are being handled.
🙂 Expected behavior
The output of the above program should be:
{ done: false, value: 1 }
{ done: false, value: 2 }
{ done: true, value: undefined }
which is in line with the behavior observed when native async generator implementation is used.