标题:搞定 koa 之generator 与 co 出处:刘新修 时间:Wed, 17 May 2017 17:29:07 +0000 作者:刘新修 地址:http://liuxinxiu.com:80/generator_co/ 内容: koa 是由 tj大神利用 generator 开发的 web 框架。要理解 koa,首先要先了解 generator 与 co。作为搞定 koa 的第一篇,我们便谈谈这个。文章首发在boke.io generator介绍 function* Gene(){ yield 1; yield 2; } var gene = Gene(); console.log(gene.next());//{ value: 1, done: false } console.log(gene.next());//{ value: 2, done: false } console.log(gene.next());//{ value: undefined, done: true } console.log(gene.next());//Error: Generator has already finished 经@Ralph-Wang提醒从 v0.11.13 开始不抛错了,返回{ value: undefined, done: true } 从上面我们可以看到 generator 的定义和函数类似,只是在 function 后面多了一个* 调用generator 和调用函数一样,只是不像函数立即执行,而是会生成一个对象 generator 生成的对象存在一个 next 函数,调用 next 会返回 yield运算的结果对象,并停止。再次调用会在下一个 yield 处停止。 当所有的 yield 被执行完,调用 next 函数会返回{ value: undefined, done: true }。再次调用会报错 generator 与异步 看完 generator 的介绍,你心里回想这跟异步有毛关系?不着急听我接着说 串行请求两个网页的代码 var request = require('request'); var a = {}; var b = {}; request('http://www.google.com', function (error, response, body) { if (!error && response.statusCode == 200) { a.response = response; a.body = body; request('http://www.yahoo.com', function (error, response, body) { if (!error && response.statusCode == 200) { b.response = response; b.body = body; } }); } }); 我们再看看最终我们是如何利用 generator请求网页的 co(function *(){ var a = yield request('http://google.com'); var b = yield request('http://yahoo.com'); console.log(a[0].statusCode); console.log(b[0].statusCode); })() 上面的代码可以看到,co 里面传入了一个 generator,里面用 yield 调用异步函数。从逻辑上看,里面的异步被变成了同步。 co 到底有什么魔法?可以把我们从异步中解救出来? 想想 generator 的特性,当我们执行第一个 next 的时候,会调用第一个 request,此时我们去调用 request 的逻辑,然后把 generator 的实例穿进去。当第一个 request 逻辑完成时,在调用这个 generator 的 next,这样就到了第二个 yield 的逻辑了。当然这需要一些逻辑的封装,也就是 co 了。 根据上面的分析,我们大概可以写出下面的代码 function co(Gene){ //先实例化一下 var gene = Gene(); //如果存在 next 函数 if(gene.next){ var fun = gene.next();//把异步函数返回过来,好继续封装 //fun 处理完,再调用 gene.next() //... } } 从上面的代码可以看出 yield 后面的内容需要返回一个异步函数,这样我们才可进一步封装异步处理的逻辑。 fun 需要可以传入参数,这样才可以处理多个异步 需要一个递归调用,这样才可以持续调用 next,同时根据 next 返回对象中的done属性停止逻辑 需要考虑错误处理 今天就到这里,下一篇详细讲一下 co 的源码 Generated by Bo-blog 2.1.1 Release