简述 Generator

93 阅读2分钟

什么是Generator?

  • Generator函数是ES6提供的一种异步方案,可以被称为“状态机”函数。
  • 核心是function*yieldnext*yieldnext*的配合。
    • function*相当于强化版的function,是赋予了解析yield关键字的function
    • yield表达式确立该状态机的一种状态,yield只能在function*函数内被使用,一个function*函数内可以有多个yield表达式,每个yield声明一种状态。
    • next用于function*的函数调用,每次调用会让function*切换到下一个状态,在最后一个yield表达式或return后,再调用next将无法切换状态也无法获得有意义的返回值。
    • yield*用于解析function*内嵌的function*,相当于Promise函数只能用then来链式调用。

举几个例子

最简单的声明与调用:

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

var hw = helloWorldGenerator();

hw.next()
// { value: 'hello', done: false }

hw.next()
// { value: 'world', done: false }

hw.next()
// { value: 'ending', done: true }

hw.next()
// { value: undefined, done: true }

Generator内嵌Generator的声明与调用:

function* bar() {
  yield 'x';
  yield* foo();
  yield 'y';
}

// 等同于
function* bar() {
  yield 'x';
  yield 'a';
  yield 'b';
  yield 'y';
}

// 等同于
function* bar() {
  yield 'x';
  for (let v of foo()) {
    yield v;
  }
  yield 'y';
}

for (let v of bar()){
  console.log(v);
}
// "x"
// "a"
// "b"
// "y"

Generator带来的异步方案

在Generator之前,异步编程的解决方案大概有以下四种:

  • 回调函数
  • 事件监听
  • 发布/订阅
  • Promise 对象

Generator提供的异步方案既不强依赖于回调函数与事件监听,也不需要像发布/订阅以及Promise那样即时反馈。它提供了一种优雅的异步方案,让你可以在获取关键数据或者触发关键操作后的任意时刻触发后续操作,甚至可以在获取后续所有步骤的所有关键数据/操作后,直接触发一系列的异步处理。