yield 关键字用来暂停和恢复一个生成器函数((function* 或遗留的生成器函数)。
语法
[rv] = yield [expression];
expression
定义通过迭代器协议从生成器函数返回的值。如果省略,则返回undefined。rv
返回传递给生成器的next()方法的可选值,以恢复其执行。
描述
yield关键字使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。
yield关键字实际返回一个IteratorResult对象,它有两个属性,value和done。value属性是对yield表达式求值的结果,而done是false,表示生成器函数尚未完全完成。
一旦遇到 yield 表达式,生成器的代码将被暂停运行,直到生成器的 next() 方法被调用。每次调用生成器的next()方法时,生成器都会恢复执行,直到达到以下某个值:
yield,导致生成器再次暂停并返回生成器的新值。 下一次调用next()时,在yield之后紧接着的语句继续执行。throw用于从生成器中抛出异常。这让生成器完全停止执行,并在调用者中继续执行,正如通常情况下抛出异常一样。- 到达生成器函数的结尾;在这种情况下,生成器的执行结束,并且
IteratorResult给调用者返回undefined并且done为true。 - 到达
return语句。在这种情况下,生成器的执行结束,并将IteratorResult返回给调用者,其值是由return语句指定的,并且done为true。
如果将参数传递给生成器的next()方法,则该值将成为生成器当前yield操作返回的值。
在生成器的代码路径中的yield运算符,以及通过将其传递给Generator.prototype.next()指定新的起始值的能力之间,生成器提供了强大的控制力。
示例
以下代码是一个生成器函数的声明。
function* countAppleSales () {
var saleList = [3, 7, 5];
for (var i = 0; i < saleList.length; i++) {
yield saleList[i];
}
}
一旦生成器函数已定义,可以通过构造一个迭代器来使用它。
var appleStore = countAppleSales(); // Generator { }
console.log(appleStore.next()); // { value: 3, done: false }
console.log(appleStore.next()); // { value: 7, done: false }
console.log(appleStore.next()); // { value: 5, done: false }
console.log(appleStore.next()); // { value: undefined, done: true }
yield*
yield* 表达式用于委托给另一个generator 或可迭代对象。
语法
yield* [[expression]];
expression
返回一个可迭代对象的表达式。
描述
yield* 表达式迭代操作数,并产生它返回的每个值。
yield* 表达式本身的值是当迭代器关闭时返回的值(即done为true时)。
示例
委托给其他生成器
以下代码中,g1() yield 出去的每个值都会在 g2() 的 next() 方法中返回,就像那些 yield 语句是写在 g2() 里一样。
function* g1() {
yield 2;
yield 3;
yield 4;
}
function* g2() {
yield 1;
yield* g1();
yield 5;
}
var iterator = g2();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: 4, done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
委托给其他可迭代对象
除了生成器对象这一种可迭代对象,yield* 还可以 yield 其它任意的可迭代对象,比如说数组、字符串、arguments 对象等等。
function* g3() {
yield* [1, 2];
yield* "34";
yield* arguments;
}
var iterator = g3(5, 6);
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: "3", done: false }
console.log(iterator.next()); // { value: "4", done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: 6, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
yield* 表达式的值
yield* 是一个表达式,不是语句,所以它会有自己的值。
function* g4() {
yield* [1, 2, 3];
return "foo";
}
var result;
function* g5() {
result = yield* g4();
}
var iterator = g5();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true },
// 此时 g4() 返回了 { value: "foo", done: true }
console.log(result); // "foo"
博客主要介绍了生成器函数中关键字的作用,它能使函数执行暂停并返回值,还说明了其返回对象的属性。同时阐述了遇到不同情况时生成器的执行状态。此外,对yield*表达式进行讲解,包括其语法、描述及示例,如委托给其他生成器或可迭代对象等。
1298

被折叠的 条评论
为什么被折叠?



