nodejs上有很多用来解决callback-hell的包, 有的是做一点语法糖, 有的用到了generator, 有的从底层实现类似协程的方式. 如async, co, 各种promise, es7的async/await等. co4也要求结合promise使用了. 说实在的, 我不喜欢promise, 太麻烦, 思维习惯转不过来. 所以一直都是在用fibers来用于实际开发, 后来在项目中慢慢积累, 就出来了现在这个包: nbs.
先来个例子吧:
var nbs = require('nbs'), wait = nbs.wait, resume = nbs.resume;
function sleep(ms){
setTimeout(function(){
resume();
}, sec);
wait();
}
nbs.run(function(){
console.time('sleep');
//sleep 1s
setTimeout(resume, 1000);
wait();
//call the sleep method
sleep(1000);
//return a value from resume param
setTimeout(resume.bind(null, 'wake up'), 1000);
console.log(wait());//wake up
console.timeEnd('sleep');//almost 3000ms
});
跟fibers语法很像, 不过已经省去了额外的引用(Fiber.current), api也更加明朗. fibers设计上没有区分run/resume, 这里也给分开了.
主要特性
- 使用
run/wait/resume实现协程功能, 可避免洋葱回调 - 也无需使用额外的引用来调用
wait和resume - 加强了错误处理(内部集成了domain), 可通过向resume传入err参数抛出异常
- 加强了嵌套调用. 你可以在第n层回调下调用resume, 也可以在一个异步中额外启动一个协程栈
- 对于同步回调, 也能正常地resume/wait
- 提供了一个express中间件
并发发起异步IO
function get(url, cb){//get the response data from url
//cb(err, data)
}
nbs.run(function(){
get('url1', resume);
get('url2', resume);
get('url3', resume);
//data1 may not be the url1's result! it can be url2/url3's result too.
//you should not rely on that. same to data2/data3
var data1 = wait()[1];
var data2 = wait()[1];
var data3 = wait()[1];
console.log(data1, data2, data3);
});
各位感兴趣的可以看一下, 欢迎讨论, 轻拍:)