ES6 Generator

今天讨论的新特性让我很是兴奋,由于这个特性是 ES6 中最神奇的特性。html

这里的“神奇”意味着什么呢?对于初学者来讲,该特性与以往的 JS 彻底不一样,甚至有些晦涩难懂。从某种意义上说,它彻底改变了这门语言的一般行为,这不是“神奇”是什么呢。git

不只如此,该特性还能够简化程序代码,将复杂的“回调堆栈”改为直线执行的形式。程序员

我是否是铺垫的太多了?下面开始深刻介绍,你本身去判断吧。github

简介

什么是 Generator?web

看下面代码:多线程

上面代码是模仿 Talking cat(当下一个很是流行的应用)的一部分,点击这里试玩,若是你对代码感到困惑,那就回到这里来看下面的解释。函数

这看上去很像一个函数,这被称为 Generator 函数,它与咱们常见的函数有不少共同点,但还能够看到下面两个差别:post

  • 一般的函数以 function 开始,但 Generator 函数以 function* 开始。
  • 在 Generator 函数内部,yield 是一个关键字,和 return 有点像。不一样点在于,全部函数(包括 Generator 函数)都只能返回一次,而在 Generator 函数中能够 yield 任意次。yield 表达式暂停了 Generator 函数的执行,而后能够从暂停的地方恢复执行。

常见的函数不能暂停执行,而 Generator 函数能够,这就是这二者最大的区别。性能

原理

调用 quips() 时发生了什么?ui

咱们对普通函数的行为很是熟悉,函数被调用时就当即执行,直到函数返回或抛出一个异常,这是全部 JS 程序员的次日性。

Generator 函数的调用方法与普通函数同样:quips("jorendorff"),但调用一个 Generator 函数时并无当即执行,而是返回了一个 Generator 对象(上面代码中的 iter),这时函数就当即暂停在函数代码的第一行。

每次调用 Generator 对象的 .next() 方法时,函数就开始执行,直到遇到下一个 yield 表达式为止。

这就是为何咱们每次调用 iter.next() 时都会获得一个不一样的字符串,这些都是在函数内部经过 yield 表达式产生的值。

当执行最后一个 iter.next() 时,就到达了 Generator 函数的末尾,因此返回结果的 .done属性值为 true,而且 .value 属性值为 undefined

如今,回到 Talking cat 的 DEMO,尝试在代码中添加一些 yield 表达式,看看会发生什么。

从技术层面上讲,每当 Generator 函数执行遇到 yield 表达式时,函数的栈帧 — 本地变量,函数参数,临时值和当前执行的位置,就从堆栈移除,可是 Generator 对象保留了对该栈帧的引用,因此下次调用 .next() 方法时,就能够恢复并继续执行。

值得提醒的是 Generator 并非多线程。在支持多线程的语言中,同一时间能够执行多段代码,并伴随着执行资源的竞争,执行结果的不肯定性和较好的性能。而 Generator 函数并非这样,当一个 Generator 函数执行时,它与其调用者都在同一线程中执行,每次执行顺序都是肯定的,有序的,而且执行顺序不会发生改变。与线程不一样,Generator 函数能够在内部的 yield 的标志点暂停执行。

经过介绍 Generator 函数的暂停、执行和恢复执行,咱们知道了什么是 Generator 函数,那么如今抛出一个问题:Generator 函数到底有什么用呢?

 

参考:http://web.jobbole.com/82903/