Generator函数的中断与恢复

Generator是JS中一种特殊的函数,它能通过迭代器协议(Iterator Protocol)实现中断与恢复功能。

Generator函数使用function* 声明,调用Generator函数时不会立即执行,而是返回一个迭代器对象。通过调用迭代器的next()方法,可以逐步执行Generator函数。Generator函数内部可以使用yield关键字定义中断点。当调用next()时,会从上次暂停的地方继续执行,直到遇到下一个yield关键字或函数结束。通过不断调用next()方法,可以逐步执行Generator函数,并获取每个中断点处的值。

function* generatorFunction() {
console.log("1");
yield;
console.log("2");
yield;
console.log("3");
}
const generator = generatorFunction();
generator.next(); // 1
generator.next(); // 2
generator.next(); // 3

由于Generator函数具有中断和恢复的特性,可以用于异步编程。通过yield关键字,将异步操作分割成多个步骤,每个步骤都可以通过yield暂停,等待异步操作完成后再恢复执行。

获取中断点处的值

function* generatorFunction() {
yield "hello";
yield "world";
yield "ending";
}
const generator = generatorFunction();
const a = generator.next(); // { value: "hello", done: false }
const b = generator.next(); // { value: "world", done: false }
const c = generator.next(); // { value: "ending", done: true }
const d = generator.next(); // { value: undefined, done: true }

yield*

yield*用来在一个Generator函数里执行另一个Generator函数。

function* foo() {
yield "aaa";
yield "bbb";
}
function* bar() {
yield * foo();
yield "ccc";
yield "ddd";
}
const generator = bar();
const a = generator.next(); // { value: "aaa", done: false }
const b = generator.next(); // { value: "bbb", done: false }
const c = generator.next(); // { value: "ccc", done: false }
const d = generator.next(); // { value: "ddd", done: false }
const e = generator.next(); // { value: undefined, done: true }

bar里面,执行到e这一步done才变成true是因为,bar实际上相当于是

function* bar() {
yield * foo();
yield "ccc";
yield "ddd";
return undefined;
}

所以遇到return才done。

next()的参数

yield表达式本身没有返回值。比如

const result = yield 3 + 4 + 5;

当执行到yield 3 + 4 + 5的时候会暂停;当执行next()方法后,此时执行const result = [yield 3 + 4 + 5],这个时候result的值是undefined

但是next()可以传一个参数,这个参数会被当作yield的返回值。因此如果执行next(10),此时result的值则为10。即const result = next(10)

for...of

迭代器对象(Iterator)可以使用for...of遍历。这里需要注意,一旦next()方法的返回对象的done属性为truefor...of循环就会终止,且不包含该返回对象。

function* generatorFunction() {
yield 1;
yield 2;
yield 3;
yield 4;
return 5;
}
for (const item of generatorFunction()) {
console.log(item);
}
// 1
// 2
// 3
// 4

Generator.prototype.return

return方法可以提前终结遍历器函数

function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
const generator = generatorFunction();
generator.next(); // { value: 1, done: false }
generator.return("end"); // { value: "end", done: true }
generator.next(); // { value: undefined, done: true }
评论加载中 (ง •̀ω•́)ง