ES6 Generator

定义

ES6 提供的一种异步编程解决方案

有多种理解角度:

  • 语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。
  • 执行 Generator 函数会返回一个遍历器对象,是Iterator的一种实现,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数
  • 形式上,Generator 函数是一个普通函数(不能当构造器函数使用),但是有两个特征:
    • function关键字与函数名之间有一个星号
    • 函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。
调用与执行

Generator 函数的调用方法与普通函数一样,在函数名后面加上一对圆括号。不同的是,调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,也就是遍历器对象(Iterator Object),不是this对象(获取不到Generator 函数里面定义的属性)

下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。换言之,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。

yield表达式

yield表达式是Generator 函数的暂停标志。遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

yield表达式本身没有返回值,或者说总是返回undefinednext方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。

方法
  • next():使得指针移向下一个状态,返回一个对象,这个对象包含两个属性:valuedonevalue 属性表示本次 yield 表达式的返回值,done 属性为布尔类型,表示生成器后续是否还有 yield 语句,即生成器函数是否已经执行完毕并返回。
  • throw():在函数体外抛出错误,然后在 Generator 函数体内捕获。
  • return():返回给定的值,并且终结遍历Generator 函数。

共同特点:让 Generator 函数恢复执行,并且使用不同的语句替换yield表达式。

示例
function* f() {
  for(var i = 0; true; i++) {
    var reset = yield i;
    if(reset) { i = -1; }
  }
}

var g = f();

g.next() // { value: 0, done: false }
g.next() // { value: 1, done: false }
g.next(true) // { value: 0, done: false }
参考资料

MDN Generator
ES6 generator

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):