生成器Generators/yield

Generator Function(生成器函数)和Generator(生成器)是ES6引入的新特性,该特性早就出现在了Python、C#等其他语言中。生成器本质上是一种特殊的迭代器https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/The_Iterator_protocol

Generator函数本意是iterator生成器,函数运行到yield时退出,并保留上下文,在下次进入时可以继续运行。

生成器函数也是一种函数,语法上仅比普通function多了个星号 ,即function ,在其函数体内部可以使用yield和yield* 关键字。

简单理解,这是ES6的新特性,function 后面带 * 的叫做Generator,如以下代码所示。

执行示例

  1. function* doSomething() {
  2. ....
  3. }

先看一下Generator如何执行:

  1. function* doSomething() {
  2. console.log('1');
  3. yield; // Line (A)
  4. console.log('2');
  5. }
  6. var gen1 = doSomething();
  7. gen1.next(); // Prints 1 then pauses at line (A)
  8. gen1.next(); // resumes execution at line (A), then prints 2

说明

  • gen1是产生出来的Generator对象
  • 第一个next,会打印出1,之后悬停在 yield所在行,即Line (A)
  • 第二个next,恢复line (A)点的执行,之后打印出2

next的返回结果说明

  1. function* doSomething() {
  2. console.log('1');
  3. yield; // Line (A)
  4. console.log('2');
  5. }
  6. var gen1 = doSomething();
  7. console.log(gen1.next()); // {value:'', done: false}
  8. console.log(gen1.next()); // {value:'', done: true}

第1个gen1.next()结果

  1. next的返回对象{value:'', done: false}

第2个gen1.next()结果

  1. next的返回对象{value:'', done: true}

如果done为true,则代表generator里的yield都完成了。这直接关系到后面的co实现,所以此处必须理解。

如果generator里有多个yield呢?

如果generator里有多个yield呢?

那么会有无穷无尽的next。

于是tj就写co这个著名的Generator执行器,co目前已经是v4了,彻底的面向Promise了,个中曲折也是够八卦的了。

这就是下一节要讲的内容。