Generator函数的中断与恢复

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

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

ts
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暂停,等待异步操作完成后再恢复执行。

获取中断点处的值

ts
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函数。

ts
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实际上相当于是

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

所以遇到return才done。

next()的参数

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

ts
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循环就会终止,且不包含该返回对象。

ts
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方法可以提前终结遍历器函数

ts
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 }
在GitHub上编辑
上次更新于:
评论加载中 (ง •̀ω•́)ง