00:56
<Mathieu Hofman>

Something is confusing me about AsyncGeneratorStart / AsyncGeneratorCompleteStep. Is the return value of an async generator not awaited? Does that mean the final iterator result may have a promise as its value ? From my testing that doesn't seem to be the case, but I don't see how that's happening in the spec.

(async function * () { return Promise.resolve(42); })().next().then(x => console.log(x)); // { value: 42, done: true }
01:21
<bakkot>
awaiting of return values actually happens as part of the evaluation of the return itself
01:22
<bakkot>
https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html#sec-return-statement-runtime-semantics-evaluation
01:24
<Mathieu Hofman>
Oh that is wild!
01:32
<bakkot>
This way it triggers finally statements
01:32
<bakkot>
Which, also kinda weird
02:59
<Mathieu Hofman>
I'm not sure I understand, `finally` always executes if a `return` is in a `try`. Internally awaiting the return expression shouldn't change that. And if there was a `catch` it shouldn't trigger it, in the same way `yield`ing a rejected promise only triggers a `catch` if the consumer of the iterator called `throw`. (I might have gotten myself confused again with generator behaviors and afk so can't easily double check)
04:08
<bakkot>
sorry, I meant catch not finally
04:08
<bakkot>
and it doe trigger a catch
04:08
<bakkot>
(async function*(){ try { return Promise.reject('hi'); } catch (e) { console.log('caught', e); } })().next()
// caught hi
04:09
<bakkot>

this is in contrast to async functions

(async function(){ try { return Promise.reject('hi'); } catch (e) { console.log('caught', e); } })().catch(e => console.log('did not catch', e))
// did not catch hi
04:09
<bakkot>
yielding a rejected promise does also trigger a catch incidentally
04:10
<bakkot>
which I am pretty sure is why return works that way in async generators
07:20
<Mathieu Hofman>
Well at least it's consistent. And now that you mention it, I think I knew that and just forgot about that oddity.