写nodejs时,不可避免的需要用到回调函数,谁让人家有异步io特性,有时候可能需要多层嵌套造成‘回调金字塔’,下面是我看到的一些解决方案,总结一下以方便自己日后查看(我目前确实还没有达到这种要写到让人眼花的嵌套回调)……
1.EventProxy事件代理方式
github地址:https://github.com/JacksonTian/eventproxy
官方介绍:
EventProxy 仅仅是一个很轻量的工具,但是能够带来一种事件式编程的思维变化。有几个特点:
利用事件机制解耦复杂业务逻辑
移除被广为诟病的深度callback嵌套问题
将串行等待变成并行等待,提升多异步协作场景下的执行效率
友好的Error handling
无平台依赖,适合前后端,能用于浏览器和Node.js
兼容CMD,AMD以及CommonJS模块环境
代码展示:
var ep = EventProxy.create("template", "data", "l10n", function (template, data, l10n) {
_.template(template, data, l10n);
});
$.get("template", function (template) {
// something
ep.emit("template", template);
});
$.get("data", function (data) {
// something
ep.emit("data", data);
});
$.get("l10n", function (l10n) {
// something
ep.emit("l10n", l10n);
});
简单理解就是把需要异步回调的函数按执行顺序把函数写在一个地方。
2.async异步流程控制
github地址:https://github.com/caolan/async
官方介绍(翻译):
Async是一个高效的能够让我们直接写出异步js函数,虽然最初是为nodejs设计出来的,但也能直接用于浏览器。
代码展示:
var concurrencyCount = 0;
var fetchUrl = function (url, callback) {
// delay 的值在 2000 以内,是个随机的整数
var delay = parseInt((Math.random() * 10000000) % 2000, 10);
concurrencyCount++;
console.log('现在的并发数是', concurrencyCount, ',正在抓取的是', url, ',耗时' + delay + '毫秒');
setTimeout(function () {
concurrencyCount--;
callback(null, url + ' html content');
}, delay);
};
var urls = [];
for(var i = 0; i < 30; i++) {
urls.push('http://datasource_' + i);
}
async.mapLimit(urls, 5, function (url, callback) {
fetchUrl(url, callback);
}, function (err, result) {
console.log('final:');
console.log(result);
});
代码借鉴自这里:https://github.com/alsotang/node-lessons/tree/master/lesson5
这里是通过Async的API–mapLimit来控制请求的并发数量。
3.使用promise代替回调
详情看这里:https://github.com/alsotang/node-lessons/tree/master/lesson17
4.es6的generator函数
详细介绍:http://es6.ruanyifeng.com/#docs/generator
具体几种方法的各自优势,待我在真实场景用过后,再补充…….