yield 关键字用来暂停和恢复一个生成器函数(function*
)
举例:
function* gen(index) {
while (index < 2) {
yield index++;
}
}
const iterator = gen(0);
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
// 0
// 1
// undefined
[rv] = yield [expression];
undefined
。next()
方法的可选值,以恢复其执行。yield
关键字使 生成器函数 暂停执行,yield
关键字后面的表达式的值 返回给生成器的调用者。可以理解成是一个基于生成器的版本的return关键字。(It can be thought of as a generator-based version of the return keyword.)
yield只能从直接包含它的生成器函数中调用。不能从嵌套函数或回调中调用它。
yield关键字会导致对生成器的next()
方法的调用,这个方法会返回具有两个属性value
和done
的IteratorResult对象。value
属性是对yield
后面跟的表达式求值的结果,当done
值为false
时,表示生成器函数尚未完全完成。
一旦遇到 yield 表达式,生成器的代码执行就会暂停,直到生成器的 next()
方法再次被调用。每次调用生成器的next()
方法时,生成器都会恢复执行,直到遇到以下情况:
next()
方法时,在yield
之后紧接着的语句将继续执行。value
属性的值是undefined
,done
属性为true
。return
语句。在这种情况下,生成器执行结束,并将IteratorResult返回给调用者,其value
属性的值是return
语句后面表达式的值的,done
属性 为true
。如果给生成器中的next()
方法传递参数,则该值将成为生成器当前yield
操作返回的值。
在整个生成器代码运行中,yield
操作符,以及向Generator.prototype.next()
方法中传递一个参数指定起始值,生成器提供了强大的控制作用。。。
举例:
下面的代码声明了一个 生成器函数:
function* countName(){
let name = ['happy','chen','666'];
for (let i = 0; i < name.length; i++) {
yield name[i];
}
}
一旦生成器函数已定义,可以通过构造一个迭代器来使用它:
function* countName(){
let name = ['happy','chen','666'];
for (let i = 0; i < name.length; i++) {
yield name[i];
}
}
let nameIterator = countName();
console.log(nameIterator.next());
console.log(nameIterator.next());
console.log(nameIterator.next());
console.log(nameIterator.next());
// { value: 'happy', done: false }
// { value: 'chen', done: false }
// { value: '666', done: false }
// { value: undefined, done: true }
yield* 表达式用于委托给另一个generator 或可迭代对象。
yield* [[expression]];
yield*
表达式迭代操作数,并产生它返回的每个值。yield*
表达式本身的值是当迭代器关闭时返回的值(即done为true时)。
举例:
以下代码中,g1() yield 出去的每个值都会在 g2() 的 next()
方法中返回,就像那些 yield 语句是写在 g2() 里一样。(values yielded by g1() are returned from next()
calls just like those which are yielded by g2().)
function* g1() {
yield 2;
yield 3;
yield 4;
}
function* g2() {
yield 1;
yield* g1();
yield 5;
}
let iterator = g2();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
// { value: 1, done: false }
// { value: 2, done: false }
// { value: 3, done: false }
// { value: 4, done: false }
// { value: 5, done: false }
// { value: undefined, done: true }
除了生成器对象这一种可迭代对象,yield* 还可以 yield 其它任意的可迭代对象,比如说数组、字符串、arguments 对象等等。(Besides generator objects, yield* can also yield other kinds of iterables, e.g. arrays, strings or arguments objects.)
function* g3() {
yield* ['happy', 'chen'];
yield* 'is';
yield* Array.from(arguments);
}
let iterator = g3('a', 'Front-end', 'development', 'engineer');
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
// { value: 'happy', done: false }
// { value: 'chen', done: false }
// { value: 'i', done: false }
// { value: 's', done: false }
// { value: 'a', done: false }
// { value: 'Front-end', done: false }
// { value: 'development', done: false }
// { value: 'engineer', done: false }
// { value: undefined, done: true }
yield 是一个表达式*,不是语句,所以它会有自己的值。
function* g4(){
yield* [5,2,0];
return '可达鸭';
}
let result;
function* g5(){
result = yield* g4();
}
let iterator = g5();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(result);
// { value: 5, done: false }
// { value: 2, done: false }
// { value: 0, done: false }
// { value: undefined, done: true }
// 可达鸭