浅析KOA(1)

发布时间:2019-08-20 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了浅析KOA(1)脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

起因

起步学node比较晚,所以没看exPress,直接看了koa,但是多数组件都是通过callback回调来执行,无法直接在koa中使用,所以了解了下koa的实现原理,以便包装现有组件或方法,这里记录下来细节,以作备份,并给大家做个参考吧。

koa依赖co,配合thunkify来执行,虽然co现在已经改成基于promise实现了,但其实原理基本差不多,我这里先分析下co3.x版本。

( 这里需要你对 generator 有一定了解 )

分析

核心是利用generator可以挂起或next(res)来继续执行方法的特性。

这里不考虑异常处理流程,结合适当伪码,给出一个简易的demo便于理解co的控制流程:

常规异步嵌套代码:

fs.reaDFile('template.htML', function (err, template) { // 读取模板
  asynCFunc('data.json', function (err, data) { // 获取数据
    rep.end(render(template, data)); // 装配并返回
  });
});

(注:上面的代码仅作示意,并不考虑效率因素。实际上如果模板和数据都是异步的,我们应该同时发起请求,co推荐将异步操作组成数组或对象,它在内部会做平行处理以便优化速度)

我们期望的同步写法:

VAR tempalte = readFile('template.html');
var data = asyncFunc('data.json');
rep.end(render(template, data));

为了实现这个功能,我们利用generator的特性,先做一个工具方法迭代generator:

function core(genfunc) {
  var g = genfunc();

  (function next(err, res) {
    res = g.next(res);
    if (!res.done) {
      res.value(next);
    }
  })();
}

上面这个方法接收一个generatorFunction作为参数,然后实例化它生成迭代器g,next方法不停的反复调用g,并将上一次的返回值作为参数不停的传递下去(有点像PRomise链式调用)。这里有个地方注意:生成器每次返回的值必须是一个方法,并接受fn回调参数,这样next方法才能作为参数不停的迭代下去(co支持多种数据类型,它自行包装了这些数据类型,最终还是返回方法)

那么下面就差最后一步了,包装node标准api中的异步方法,以便支持yield

function thunkify(fn) {
  return function () {
    var args = Array.prototyPE.slice.call(arguments, 0);
    return function (next) {
      fn.apply(this, args.concat(next));
    }
  }
}
// 包装原生API
var readFile = thunkify(fs.readFile);

现在当调用readFile('path')的时候返回的是一个方法了,也就是yield的返回值,通过在core方法中,我们来调用这个方法,并将next作为参数传递给它,于是整个流程就可以以同步方式执行下去了,我们将刚才的同步代码通过core进行包装,最终得到:

core(function*() {
  var tempalte = yield readFile('template.html');
  var data = yield asyncFunc('data.json');
  rep.end(render(template, data));
});

结论

这里asyncFunc我用来表示任何异步方法,它应该与readFile类似,返回另一个方法并接受callback回调。标准API通常可以通过thunkify来直接wrap,但如果是自己实现的方法必须要遵守这个约定。

以上代码依赖generator特性,需要安装最新版的node,当前最新版本是0.11.15,通过--harmony参数启动,推荐安装iojs,支持es6多数语法,用来学习了解新语法不错。

脚本宝典总结

以上是脚本宝典为你收集整理的浅析KOA(1)全部内容,希望文章能够帮你解决浅析KOA(1)所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。