Learning Card
- Generator函数是什么
- 状态机+遍历器
- 可以暂停的函数
- 解决异步
- Generator函数的特征
function与函数名直接有星号- 函数内部有
yield表达式 - 函数用
next()语句调用
yield返回值next()调用返回的对象的value值是yield后面的值- 如果没有,就返回
undefined
next()传参next()中的参数作为上一个yield语句的返回值- 第一个
next()传的参数总是无效
Generator函数是什么
Generator函数也是解决异步操作的一种方案。阮大大在《ES6入门》里给Generator下了两个定义,一个是它是“一个状态机,封装了多个内部状态”,第二个是它还是一个“遍历器对象生成器”,可以遍历Generator函数内部的每一个状态。
这些术语听起来有点复杂,个人觉得Blue在ES6的课程里说的解释比较容易记住,Generator函数是一个可以中途停下来的函数,你push它一下,它就往前进一步。
Generator函数的特征
Generator函数的写法和普通函数有三个不同:
function关键字和函数名之间有一个星号(星号的位置可以挨着function,也可以挨着函数名,也可以在function和函数名直接,但是不能function*函数名三个连起来- 函数内部有
yield表达式,让函数执行过程中可以停下来 - 函数的调用必须使用
next()
1 | function show() { |
yield返回值
yield既可以传参,又可以返回值,我们先来看看yield如何返回值。
从上面那段代码中可以看到,Generator是一个遍历器对象,调用Generator函数并不会立即执行,而是返回一个指向内部状态的指针对象,如果我们将show.next()打印出来,可以看到实时上,它是一个包含了两个属性的对象,一个value属性,它的值是当前yield表达式的值,另一个是done属性,它的值是一个布尔值,表示遍历是否结束。如果当前yield没有值,那么value属性的值就是undefined。
1 | function * helloWorldGenerator() { |
如果我们画一个图来看每一次指针指向的对象的值(即遇到的需要暂停的yield后面的值)会更加清晰

三种颜色表示了三次调用Generator函数的内容。
next传参
前面我们提到了,yield后面的值会作为yield之前的对象的value值返回出去,如果yield后面没有值,那么返回的value就是undefined。但是Generator函数可以通过next()传递参数到函数内部,作为上一个yield表达式的返回值。还是用helloWorldGenerator这个例子
1 | function * helloWorldGenerator() { |
我们还是画图来看这个流程

可以看出,第一个next()语句因为之前没有出现yield语句,所以第一个next()传的参数总是无效。
ES6学习笔记的内容主要基于阮一峰老师的《ECMAScript 6入门》,原文请见链接