Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to get returned value from async generator when using for await

I have following code:

for await (const part of resolveData(data)) {
    console.log({part});
}

It iterates over an async generator that looks like this:

const resolveData = async function* <T> (data: SomeValue<T>) {
    if (<expression1>) {
        if (<expression2>) {
            console.log("valid");
            yield 1;
        }
    }
    return 2;
}

The output of the for await loop looks like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{ part: 1 }

I want to get the returned value (number 2 in this case) as well. How to get the value inside or outside of the loop?

Tried looking online but found nothing.

>Solution :

When you use return in a generator or async generator, that sets the value of value on the result object for when done is true. But for-of and for-await-of don’t run the body of the loop for the result object where done is true. Here’s a simpler example:

<script type="module">
// Note: Using an async iterator even though we never await
// because the OP's code is async
async function* example() {
    yield 1;
    return 2;
}

for await (const x of example()) {
    console.log(x);
}
</script>

(Sadly, the "JavaScript" panel in Stack Snippets can’t be run as a module, and I wanted to use top-level await, so I had to put the JavaScript in the "HTML" panel instead.)

Notice how only 1 is shown. (The same is true for for-await-of.)

You have at least two options:

1. Change your return 2 to yield 2, so that the generator isn’t "done" yet as of when it yields 2, like this:

<script type="module">
// Note: Using an async iterator even though we never await
// because the OP's code is async
async function* example() {
    yield 1;
    yield 2; // `yield` instead of `return`
}

for await (const x of example()) {
    console.log(x);
}
</script>

2. Change your code to use the iterator directly rather than using for-await-of.

<script type="module">
   // Note: Using an async iterator even though we never await
   // because the OP's code is async
   async function* example() {
       yield 1;
       return 2;
   }
   
   const it = example();
   let r;
   while (!(r = await it.next()).done) {
       console.log(r.value);
   }
   console.log(r.value);
   </script>

In both cases, you now see 1 and 2.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading