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:
{ 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.
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:
{ 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.
Share Improve this question edited Dec 28, 2023 at 15:13 sss3243 asked Dec 28, 2023 at 15:09 sss3243sss3243 955 bronze badges 1- 1 This is a typo. I meant to create only one generator – sss3243 Commented Dec 28, 2023 at 15:12
1 Answer
Reset to default 8When 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(`Value = ${r.value}, not done yet`);
}
console.log(`Value = ${r.value}, done`);
</script>
In both cases, you now see 1
and 2
.