JavaScript - Yield 操作符
JavaScript Yield 操作符
JavaScript 中的 yield 操作符用于异步暂停和恢复 generator function。在 JavaScript 中,generator 函数是可以在执行过程中暂停或恢复的特殊函数。generator 函数使用 'function*' 语法定义。yield 关键字只能在包含它的 generator 函数中使用。
yield 操作符会暂停 generator function 的执行,并将其操作数(表达式)返回给 generator 的调用者。
语法
JavaScript 中 yield 操作符的语法如下 −
yield expression;
参数
expression − 通过 iterator protocol 从 generator function 返回的值。如果省略 expression,则返回 'undefined'。
返回值
它返回传递给 generator 的 next() 方法以恢复执行的可选值。
Generator Function 中的 Yield 操作符
要理解 yield 操作符,首先让我们了解 generator function 的工作原理。
调用 generator function 时,它会返回一个 generator 对象。当调用该 generator 对象的 next() 方法时,它会恢复 generator function 的执行。当遇到 yield 表达式时,它会暂停执行,并将 yield 关键字后的表达式返回给对象的调用者(next() 方法)。
generator 对象的 next() 方法返回一个 iterator object,包含两个属性 value 和 done。value 是表达式的实际值,done 是一个布尔值。如果 generator function 执行完毕,则 done 属性为 true,否则为 false。
下面是一个完整的 generator function 示例代码,包含 yield 关键字(操作符)。
function* test() {
// 函数代码
yield expression;
}
const genObj = test();
genObj.next();
在上述语法中,'function*' 用于创建一个名为 test 的 generator function,yield 关键字用于从函数中返回 'expression'。
调用 generator function test,并将返回的 generator 对象赋值给变量 genObj。next() 方法恢复函数执行,并在遇到 yield 表达式时返回 iterator object。
让我们执行下面的 JavaScript 代码片段
function* test() {
console.log("我在 yield 表达式之前");
yield 20;
}
const genObj = test();
console.log(genObj.next());
注意,当我们调用 next() 方法时,它会先在控制台显示消息,然后显示 iterator object。
我在 yield 表达式之前
{ value: 20, done: false }
示例:返回一个值
在下面的示例中,我们定义了 test() generator function。我们在函数中使用了 3 次 yield 操作符,分别返回一个数字、一个数组和一个字符串。
之后,我们调用了 4 次 next() 方法来恢复函数的执行。每当控制流遇到 yield 操作符时,它都会停止执行并返回该值。
在输出中,你可以观察到它返回包含 yield 操作符操作数和布尔值的对象。
function* test() {
yield 20;
yield [1,2,3];
yield "Hello World";
}
let res = test();
console.log(res.next());
console.log(res.next());
console.log(res.next());
console.log(res.next());
输出
{ value: 20, done: false }
{ value: [ 1, 2, 3 ], done: false }
{ value: 'Hello World', done: false }
{ value: undefined, done: true }
示例:返回 undefined
当我们省略 yield 关键字后面的表达式时,它会返回 undefined。
function* test() {
yield;
}
let res = test();
console.log(res.next());
console.log(res.next());
输出
{ value: undefined, done: false }
{ value: undefined, done: true }
示例:向 next() 方法传递值
我们也可以向 next() 方法传递值。在下面的示例中,我们向第二个 next() 方法传递了 30。它将 yield 评估为 30。变量 result 被赋值为 yield 的值,即 30。
function* test() {
let result = yield 20;
console.log("default value paased to next() method " + result);
}
let res = test();
console.log(res.next());
console.log(res.next(30));
输出
{ value: 20, done: false }
default value paased to next() method 30
{ value: undefined, done: true }
示例
在下面的代码中,我们使用了循环,在每次操作中,使用 yield 操作符停止函数的执行。随后,我们使用 next() 方法来启动 generator function 的执行。
// Generator function
function* test() {
for (let p = 0; p < 6; p += 2) {
yield p;
}
}
let res = test();
console.log(res.next());
console.log(res.next());
console.log(res.next());
console.log(res.next());
输出
{ value: 0, done: false }
{ value: 2, done: false }
{ value: 4, done: false }
{ value: undefined, done: true }
在实际开发中,程序员使用 yield 操作符进行异步操作、惰性求值、任务调度、遍历大型数据集、创建自定义迭代器等。