Are suspended async generators supposed to resume synchronously?
brainkim opened this issue · 2 comments
I’m sure this is answered somewhere in the spec, but are async generators supposed to resume asynchronously even if there are no await calls?
Here’s how sync generators resume:
function *syncGen() {
console.log(yield 1);
console.log(yield 2);
console.log(yield 3);
return 4;
}
const gen = syncGen();
console.log(gen.next(-1));
console.log(gen.next(-2));
console.log(gen.next(-3));
console.log(gen.next(-4));
Logs:
{value: 1, done: false}
-2
{value: 2, done: false}
-3
{value: 3, done: false}
-4
{value: 4, done: true}
Iterator result logs and yield logs are interleaved, because the suspended generator is resumed synchronously.
Compare this to how async generators resume:
async function *asyncGen() {
console.log(yield 1);
console.log(yield 2);
console.log(yield 3);
return 4;
}
const gen = asyncGen() ;
console.log(gen.next(-1));
console.log(gen.next(-2));
console.log(gen.next(-3));
console.log(gen.next(-4));
Logs:
Promise {status: "pending"}
Promise {status: "pending"}
Promise {status: "pending"}
Promise {status: "pending"}
-2
-3
-4
Note that we do not await each next
result and simply call next
synchronously four times. Also note that there are no await expressions in the async generator. Why does the async generator example seem to resume asychronously? Is this a necessary result of the implementation? Can someone point to the part of the spec which defines this behavior?
Thanks!
yield
"awaits" the operand implicitly (https://tc39.es/ecma262/#sec-asyncgeneratoryield step 5)
Ah okay. I figured that yield
awaits the operand because of the promise-unwrapping behavior of async generators, but it didn’t really click for me that this would affect the execution of the rest of the generator body. I was looking at AsyncGeneratorResumeNext
and nothing there seemed to imply asynchrony.
I guess this makes sense, but I’m trying to wrap my head around why the generator has to await the yielded value
before continuing. I guess it’s because value
can be an abrupt completion (rejected promise?), and it would be unexpected if the generator was resumed even after yielding an abrupt completion.