yield*
So far aforementioned generator objects only generate a single value using yield
expression one at a time. We can also use a yield*
expression to generate a sequence of values. When a yield*
expression is encountered, sequence generation of current generator object is delegated to another generator object or iterable object.
yield*
& iterable objects
In the code below, generator function oneToThree
uses yield* [1, 2, 3]
to generate three values: 1
, 2
and 3
, which has the same result as generator function sample
in basic generators. Using yield*
expression is more concise and easier to read.
function *oneToThree() {
yield* [1, 2, 3];
}
debug(oneToThree());
// -> Output 1, 2, 3
We can use multiple yield*
expressions in a generator function, then values from each yield*
expression are generated in order.
function *multipleYieldStars() {
yield* [1, 2, 3];
yield 'x';
yield* 'hello';
}
debug(multipleYieldStars());
// -> Output 1, 2, 3, 'x', 'h', 'e', 'l', 'l', 'o'
yield*
& generator objects
We can also use other generator objects in yield*
expressions.
function *moreValues() {
yield* oneToThree();
}
debug(moreValues())
// -> Output 1, 2, 3
Value of yield*
yield*
is also an expression, so it's evaluated to a value. The value of yield*
expression depends on its target, i.e. the expression after yield*
. The value is the last value generated by the iterable object or generator object, i.e. the value
property with done
set to true
.
If yield*
is used with iterable objects, then the evaluated value is always undefined
, because the last generated value is always {value: undefined, done: true}
.
var result;
function loop(iterable) {
for (let value of iterable) {
//ignore
}
}
function *oneToThree() {
result = yield* [1, 2, 3];
}
loop(oneToThree());
console.log(result);
// -> undefined
If yield*
is used with generator objects, we can control the last generated value using return
inside of the generator functions.
var result;
function loop(iterable) {
for (let value of iterable) {
//ignore
}
}
function *abc() {
yield* 'abc';
return 'd';
}
function *generator() {
result = yield* abc();
}
loop(generator());
console.log(result);
// -> "d"