Generators are function executions that can be suspended and resumed at a later point; a
lightweight coroutine. This behavior happens using special generator functions (noted by function* > syntax) and a couple of new keywords (yield and yield*) which are only used in the context of a
generator.
曾几何时,前端的代码是这样的,主要为同步代码:
异步代码也不过是事件监听或者ajax,或者单层嵌套
不过到了node时代,代码变成了这个样子:
这就是传说中的 paramid of doom ,一种窒息的感觉迎面扑来,有木有?!
不过因为一些前辈的聪明才智,想出了一些方式来解决这种金字塔厄运式的嵌套回调,如Promise、Async等异步流程库,虽然这些库在一定程度上缓解了层层嵌套的尴尬,不过代码的复杂度依然很高,可读性不佳,我们憧憬着,要是能把异步代码写的像同步代码那样,回到我们那个纯真年代多好!(尽管我们从不曾纯真过o(╯□╰)o)
是的,银弹来了,那就是Ecmascript 6中提出的Generator,何谓渣那瑞塔?不用急,听小弟慢慢儿道来~
什么是Generator?
简单的说Generator就是一个函数执行器,能够 挂起 执行,也能够在某个时间点 恢复继续 执行 ,Generator函数用
function*
定义,函数体内使用yield
关键字来挂起,执行Generator函数后,得到一个Generator对象 ~注:以下代码都需要用
node --harmony sample.js
才可以运行来个最简单的例子
注解:
稍复杂一点(Generator的内置通信方式)
注解:
来个有趣一点的例子(依次产生群众们喜闻乐见的斐波那契数列)
注解:
Generator异常机制
注解:一般异常机制可以结合node函数/promise对象的err/fail使用~
So,这就是我们说的Generator的全部内容啦?是的,它是~
总结一下,Generator就是一种通过
function*
关键字定义Generator Function执行后的对象,叫生成器,也可以叫做迭代器,在Generator Function中可以使用yield
/yield*
来设置程序执行挂起点,Generator对象通过next()函数执行类似在函数中一个一个断点跳转的逻辑,每次执行next(),都能返回一个对象,其中指明了 yielded / returned的值(next().value),以及当前Generator对象是否已经结束的值(next().done),还能通过throw
函数抛出异常,另外next()还可传入参数,参数被当成是上一个yield语句的返回值~试想一下,假如上边的例子yield的是一种已知的异步函数,即我们已经知道这种异步函数的回调机制,结合上边介绍的Generator能力,等待异步函数执行完毕,拿到result后用
gen.next(result)
返回,我们岂不是可以获得一种将异步代码写成同步代码的能力?
如何更好的使用Generator?
试想一下,使用者不需要知道Generator的实现细节,不需要知道next调用,也不需要知道next()的返回值,更不需要根据done/value来控制程序执行流程,只需要预期yield的返回数据,直接使用,这样不就实现了所谓的将异步代码写成同步形式了么?
参考如下代码:
注解:
其实不仅仅是promise能够支持异步代码同步化的场景,理论上所有 具有明确回调调用方式async(next)以及回调函数签名function(err, ret) 的异步函数都能够在扩展run函数的实现上予以支持,有点抽象,用代码说话:
示例代码如下:
将异步函数转化成
async(next)
这种格式就叫 thunkify,一般是对node原生api进行thunkify,而上面的通过传入done回调执行的异步函数async则被称为thunk
。thunkify示例代码:
更多的Generator相关资料
其实上面写的示例Generator流程控制函数run算是开源库 co 的一个简单实现,co能支持
function
/promise
/generator
/array
/object
等类型的yield值,koa 和 koa中文站 是基于Generator,类似于express
的web框架,被express作者TJ大神称为下一代web框架,也是TJ大神宣布离开node领域后唯一不肯放弃维护的一个库,魅力可见一斑~链接:
听我唠叨了这么多,怎么样,想试试Generator? 来吧,让我们愉快的搞G吧!!!