AsyncGenerator.prototype.return()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.
The return()
method of AsyncGenerator
instances acts as if a return
statement is inserted in the generator's body at the current suspended position, which finishes the generator and allows the generator to perform any cleanup tasks when combined with a try...finally
block.
Syntax
asyncGeneratorInstance.return()
asyncGeneratorInstance.return(value)
Parameters
value
Optional-
The value to return.
Return value
A Promise
which resolves with an Object
with two properties:
done
-
A boolean value:
true
if the generator function's control flow has reached the end.false
if the generator function's control flow hasn't reached the end and can produce more values. This can only happen if thereturn
is captured in atry...finally
and there are moreyield
expressions in thefinally
block.
value
-
The value that is given as an argument, or, if the
yield
expression is wrapped in atry...finally
, the value yielded/returned from thefinally
block.
Description
The return()
method, when called, can be seen as if a return value;
statement is inserted in the generator's body at the current suspended position, where value
is the value passed to the return()
method. Therefore, in a typical flow, calling return(value)
will return { done: true, value: value }
. However, if the yield
expression is wrapped in a try...finally
block, the control flow doesn't exit the function body, but proceeds to the finally
block instead. In this case, the value returned may be different, and done
may even be false
, if there are more yield
expressions within the finally
block.
Examples
Using return()
The following example shows an async generator and the return
method.
// An async task. Pretend it's doing something more useful
// in practice.
function delayedValue(time, value) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(value), time);
});
}
async function* createAsyncGenerator() {
yield delayedValue(500, 1);
yield delayedValue(500, 2);
yield delayedValue(500, 3);
}
const asyncGen = createAsyncGenerator();
asyncGen.next().then((res) => console.log(res)); // { value: 1, done: false }
asyncGen.return("foo").then((res) => console.log(res)); // { value: "foo", done: true }
asyncGen.next().then((res) => console.log(res)); // { value: undefined, done: true }
Using return() once a generator is complete
If no value
argument is passed into the return()
method, the promise will resolve as if the next() method has been called. In this example the generator has completed, so the value returned is undefined
.
return()
can still be called after the generator is in a "completed" state, however the generator will stay in this state.
async function* createAsyncGenerator() {
yield Promise.resolve(1);
yield await Promise.resolve(2);
yield 3;
}
const asyncGen = createAsyncGenerator();
asyncGen.next().then((res) => console.log(res)); // { value: 1, done: false }
asyncGen.next().then((res) => console.log(res)); // { value: 2, done: false }
asyncGen.next().then((res) => console.log(res)); // { value: 3, done: false }
// value is returned undefined, as no value is passed and generator is 'done'
asyncGen.return().then((res) => console.log(res)); // { value: undefined, done: true }
// we can still return a value once the generator is complete
asyncGen.return(1).then((res) => console.log(res)); // { value: 1, done: true }
Specifications
Specification |
---|
ECMAScript Language Specification # sec-asyncgenerator-prototype-return |
Browser compatibility
BCD tables only load in the browser