Node.js构建高性能服务器之二—Generator
发布于 3 年前 作者 classfellow 3537 次浏览 来自 分享

本文系原创,转载请注明出处~

用Node做业务,当业务较为复杂的时候,遇到的一个困扰是回调层次变深。我相信尝试使用node的程序猿经过一段时间适应,自己的脑子在面对‘回调金字塔’的时候比其他人更加从容。但当逻辑太复杂或者需求改变需要改点儿地方的时候,‘回调金字塔’的代码结构,使得代码难以维护和阅读。

1457012716_600x818.png

se6的Generator很好解决了这个问题,使得异步的回调写起来和线性的同步编程形式一致,而运行机理又完全是异步的。换句话说,好处你都得了,性能一点儿没损失。

朴灵的一片科普Generator文章

这篇文章讲的是原理,不赘述了,下面直接贴出一段源码,

require("babel/polyfill");  // ES6 generator support in Babel
let Promise = require("bluebird")
var co = Promise.coroutine;
let rcib = require('rcib');
let postDelayBySecAsync = Promise.promisify(rcib.postDelayBySec, rcib);
let hco = co(function* () {
	yield postDelayBySecAsync(5)
	console.log('finish')
});
hco().then( function() {
      }).catch(function(e){
           console.error(e.message);
});

这是使用generator的一般形式,npm安装了这些依赖库之后,运行它,等待5s之后,打印出finish。如果使用node4.x.x的版本,运行前使用gulp工具编译一下,才能运行。

RCIB是我个人开发的一个使用C++扩展node能力的一般性框架,可以用来解决cpu密集型任务。与node使用js闭包实现异步的方法相比,rcib使用C++闭包扩展node。

被co包起来的部分,称为generator。异步函数,经过Promise.promisify 转化之后,皆可放入generator内部使用。注意,异步函数的参数需要是如下形式(p1,p2,...,function(err, data){})

以上代码如果写成一般形式,则为

rcib.postDelayBySec(5, function(err){
	console.log('finish')
})

可见使用Generator,回调的写法被展平,异步代码在形式上如同步执行。以同步之形,行异步之实。一劳永逸的解决了代码形式上多重回调嵌套的弊端。

异步的并行执行 试想,如果前后阶段的执行彼此不依赖,那么使用generator,任务执行的时间为两者处理时间之和。而处理时间可以更快,因为不依赖,所以任务处理完成的最小时间是两者单独处理时间较大的那一个。async模块有一个方法,名字叫做parallel,能够并行异步操作,收集结果,执行完需要的时间是一系列异步操作中需要时间最长的那个。pyield 支持yield并发,例如:

let hco = co(function* () {
  yield redis.set('a', 'hello a');
  yield redis.set('b', 'hello b');
  yield redis.set('c', 'hello c');

  //console.log(yield redis.get('c'));
  let allrel = yield parallelAsync([
     {obj: redis, func: redis.get, param:['a']}
    ,{obj: redis, func: redis.get, param:['b']}
    ,{obj: redis, func: redis.get, param:['c']}]);

   if(!allrel) console.error('fail');
   else console.log(allrel);
});

通过这种方式,并行执行,收集完所有结果后,将结果打印出来。

总结,本文直接给出使用Generator的一般形式,无论从一致性,代码美感,还是易用性上看,generator都是一个一劳永逸的解决方案。

上一篇文章 Node.js高性能挖掘— 1异步编程 下一篇—node.js与V8引擎

这个系列还应该包括 Node.js 与 V8引擎 内存控制与Buffer 模块加载和执行 工具类第三方模块

1 回复

rcib支持Windows,Ubuntu

回到顶部