3

Generator with return statement skips the execution of for-await-of loop.

(async () => {
  const gen = async function* () {
     return { newState: "FAILURE" };
  };
  for await (const { newState } of gen()) {
    console.log("Yey! new state is:", newState);
    // do other stuff
  }
})();

In the case written above, the whole for-await-of construction will never console.log anything. But when you swap return for yield (yield { newState: 'FAILURE' }) everything work as intended.

(async () => {
  const gen = async function* () {
    yield { newState: "FAILURE" };
  };
  for await (const { newState } of gen()) {
    console.log("Yey! new state is:", newState);
    // do other stuff
  }
})();

WHY?

0

1 Answer 1

1

The iterator never yielded anything before completing, so the loop didn't have anything to iterate - the sequence was empty. Notice you can yield multiple times but return only once.

A for … of loop ignores the return value of an iterator. It's only useful when you are manually advancing the iterator, or when using yield*.

async function* generate() {
  return { newState: "FAILURE" };
};
const generator = (async function*() {
  const { newState } = yield* generate()
  console.log("Yey! new state is:", newState);
  return "some value";
})();
generator.next().then(console.log);

This is no different for asynchronous iterators than for synchronous iterators.

Sign up to request clarification or add additional context in comments.

9 Comments

Can you please provide some docs where explicitly said that/why the for-await-of ignores return?
@Src It doesn't ignore the return statement - it stops as expected. It just doesn't have anywhere to put the return value - a for loop is not an expression with a result value.
According to the docs, yield and return both returns values, but return instead of yield returns {done:true}. So why it isn’t act like yield in this case?
Also how loop knows when to stop, because if we swap return with yield, we still get the correct result, taking into account that we don’t manually said to stop iterating, which you normally do with return
@FaizanurRahman Simply because it's sometimes useful, mostly when using generators as coroutines that have a result, not when using them to iterate something.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.