Monthly Archives: 五月 2014

Hello World

搞定异步编程(一)——使用高阶函数管理并行程序

nodejs对外宣称的最大优势就是所谓的异步io,利用异步io,可以并行执行互相没有依赖的网络、数据库等操作,在某些场景下,这种方式可以极大的提高站点的响应速度
但是异步io也带来了代码本身逻辑的复杂性,比如一个应用,需要访问三个http数据源,然后综合比较三个数据源的结果,来得出最终的返回结果
三个数据源的回调执行顺序是不定的,这就需要一个计数器,在回调次数等于3时,再执行最终的处理程序
这里,借助js的高阶函数,来实现这个逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var _httpLib = require('./lib/http.js');  //简单的http辅助类,如:get(url, callback)
//高阶函数
var pending = (function(callback){
  var count = 0, //计数
    returns = {};
  return function(key){
    count++;     //注册一个回调
    return function(data){
      count--;   //执行一个回调
      //按照并行逻辑的key保存返回结果
      returns[key] = data;
   //   returns[key] = data.substr(0, 100);
      if(count === 0){   //所有回调都执行以后,运行最终的逻辑
        callback(returns);
      }
    };
  };
});
//。。。怎么来准确的称呼done哪?
var done = pending(function(returns){
  //最终的处理逻辑
  console.log('all-------over');
  console.log(returns);
});
//三个并行数据源
_httpLib.get('http://www.baidu.com', done('baidu'));
_httpLib.get('http://www.qq.com', done('qq'));
_httpLib.get('http://www.jiangkl.com', done('jkl'));

~~~呵呵,看到一坨return、function,如果你还没晕,那么,恭喜你。反正我盯着这段代码看了不下10分钟,然后又执行了几次才算大概弄明白的
整个的逻辑,有点类似aop的思想,即对多个并行逻辑的回调做一个拦截、记录,这样可以更好的让程序员将注意力集中到业务逻辑上
pending是一个公用的并行处理函数
done是通过pending得到的具体的业务执行function,其回调参数就是前面提到的并行逻辑“最终的处理程序”
done()执行时,会将pending闭包内的计数器加1,同时返回一个function,作为httpget的回调
done()()执行时,计时器减1,同时将httpget的返回值保存
计数器减到0,“最终的处理程序”开始执行

———–
参考:http://www.infoq.com/cn/articles/generator-and-asynchronous-programming