Ben Aston
Ben Aston

Reputation: 55729

Is await necessary in async generator functions?

MDN has an example in which a generator function is marked as async, and yield is used without await.

Why is await not necessary in this example?

const myAsyncIterable = {
    async* [Symbol.asyncIterator]() {
        yield "hello"
        yield "async"
        yield "iteration!"
    }
}

Upvotes: 0

Views: 743

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370769

Just because an function is async doesn't mean that await is required. I think this example has async just to show that you could easily insert an awaited Promise into it.

Something with a Symbol.asyncIterator can be iterated over asynchronously if needed, but it doesn't have to have any asynchronous operations. You could even replace the async function with a standard generator function, on the Symbol.asyncIterator property, and still have things work just fine:

const myAsyncIterable = {
    *[Symbol.asyncIterator]() {
        yield "hello"
        yield "async"
        yield "iteration!"
    }
};

(async () => {
  for await (const item of myAsyncIterable) {
    console.log(item);
  }
})();

Looking at the specification, after the iterator is retrieved from the object, it doesn't matter whether the iterator is sync or async. An async generator function will result in an async iterator; a sync generator function will result in a sync iterator. See the final step 7 of the spec here - GetIterator will be invoked, and whatever object that's on Symbol.asyncIterator will be returned, if it exists, without regard to whether it's actually async or not.

With the iterator, when iterated over with for await, each value returned by the iterator will be awaited:

b. If iteratorKind is async, then set nextResult to ? Await(nextResult).

And it's perfectly fine to await something that isn't a Promise, it's just odd:

(async () => {
  const item = await 'foo';
  console.log(item);
})();

await will unwrap a Promise if the expression to its right is a Promise, and will leave it unchanged otherwise.

Upvotes: 2

Related Questions