nodejs常用模块async(waterfall,each,eachSeries,whilst)
来源:互联网 发布:java编程实例及讲解 编辑:程序博客网 时间:2024/06/06 01:47
这篇文章主要介绍nodejs的常用模块async,nodejs是异步io的,回头看看自己写的代码,回调函数几乎无处不在,这时候,管理好你的回调函数,理清你自己的思路就变得无比重要。(如果你还停留在闷头写代码,只是为了实现功能,那建议你放空心态,推倒重来)
先看一段代码
var objs = [{name:'A'}, {name:'B'}, {name:'C'}];function doSomething(obj, cb){ console.log("我在做" + obj.name + "这件事!"); cb(null, obj);}
我们要依次把objs中的3件事做完,顺序为A->B->C,我们可以按下面这样
doSomething(objs[0], function(err, data){ if(err) { console.log('处理错误!'); } else { doSomething(objs[1], function(err, data){ if(err) { console.log('处理错误!'); } else { doSomething(objs[2], function(err, data){ if(err) { console.log('处理错误!'); } else { console.log('处理成功!'); } }); } }); }});
嗯,层次好多,没错,这就是nodejs的异步IO的必然结果。如果我们从头想一想,回到我们做这些的事的出发点,应该如下面这样
做A这件事如果A成功,再做B这件事如果B成功,再做C这件事
安装async模块,命令行下
npm install --save async
就相瀑布一样,飞流直下三千尺,而不是一直往右缩进(tab and tab),看看async给我门的模型
var async = require('async');async.waterfall([ function(cb) { doSomething(objs[0], cb); }, function(data, cb) { doSomething(objs[1], cb); }, function(data, cb) { doSomething(objs[2], cb); }], function (err, result) { if(err) { console.log('处理错误!'); } else { console.log('处理成功!'); }});
这就是瀑布模型,先别急,我们来看看到底是发生了,我把代码添加上注释,还有运行结果,就好理解了。
var async = require('async');async.waterfall([ //A这件事 function(cb) { doSomething(objs[0], function(err, dataA){ console.log(dataA); cb(err, dataA); //如果发生err, 则瀑布就完了,后续流程都不会执行,B和C都不会执行 }); }, //B这件事,dataA就是上一步cb(err, dataA)中传进来的dataA function(dataA, cb) { doSomething(objs[1], function(err, dataB){ console.log(dataB); cb(err, dataA, dataB); //如果发生err, 则瀑布就完了,后续流程都不会执行,C不会执行 }); }, //C这件事 function(dataA, dataB, cb) { doSomething(objs[2], function(err, dataC){ console.log(dataC); cb(err, dataA, dataB, dataC); }); }], function (err, dataA, dataB, dataC) { //瀑布的每一布,只要cb(err, data)的err发生,就会到这 if(err) { console.log('处理错误!'); } else { console.log('处理成功!'); console.log(dataA); console.log(dataB); console.log(dataC); }});
console的输出
我在做A这件事!{ name: 'A' }我在做B这件事!{ name: 'B' }我在做C这件事!{ name: 'C' }处理成功!{ name: 'A' }{ name: 'B' }{ name: 'C' }
下一个要介绍的模型,whilst,一直执行主函数,直到条件不满足,或者发生异常
var async = require('async');var i = 0;async.whilst( //条件 function() { return i < 3; //true,则第二个函数会继续执行,否则,调出循环 }, function(whileCb) { //循环的主体 console.log(i); i++; whileCb(); }, function(err) { //here 如果条件不满足,或者发生异常 console.log("err is:" + err); console.log("end,the i is:" + i); });i = 0;async.whilst( function() { return i < 3; //true,则第二个函数会继续执行,否则,调出循环 }, function(whileCb) { //循环的主体 console.log(i); i++; if(i == 2) { whileCb("It's time to break."); } else { whileCb(); } }, function(err) { //here 如果条件不满足,或者发生异常 console.log("err is:" + err); console.log("end,the i is:" + i); });
程序的输出
012err is:undefinedend,the i is:301err is:It's time to break.end,the i is:2
这个模型,在有些场合下十分有用,以后说到数据库记录的版本管理的时候会说到。
第三个,each,这个就不多说了,处理记录集是每一个程序员都要遇到的问题。看例子
var async = require('async');var objs = [{name:'A'}, {name:'B'}, {name:'C'}];function doSomething(obj, cb){ console.log("我在做" + obj.name + "这件事!"); cb(null, obj);}async.each(objs, function(obj, callback) { doSomething(obj, function(){ callback(); });}, function(err){ console.log("err is:" + err);});async.each(objs, function(obj, callback) { doSomething(obj, function(){ callback("It's a err."); });}, function(err){ console.log("err is:" + err);});
再看输出
我在做A这件事!我在做B这件事!我在做C这件事!err is:undefined我在做A这件事!err is:It's a err.我在做B这件事!我在做C这件事!
第一个each相信大家都很好理解,A、B、C都顺利执行。
第二个each,相信90%的nodejs的新手程序员都不明白,因为nodejs是异步,函数必然阻塞。(同一函数同时只有一个所谓的线程执行它),也就是不存在所谓的线程安全问题(这句定义其实本身又存在问题,因为异步会导致必然的上一层共享数据的安全问题,也就是说,nodejs不会有同层次的线程安全问题),得先理解,什么是栈。
第四个,eachSeries,这个和each差不多,简单些,就是遍历每一个对象是分步的,上一个对象的callback执行完之后,在执行下一个。
var async = require('async');var objs = [{name:'A'}, {name:'B'}, {name:'C'}];function doSomething(obj, cb){ console.log("我在做" + obj.name + "这件事!"); cb(null, obj);}async.eachSeries(objs, function(obj, callback) { doSomething(obj, function(){ callback(); });}, function(err){ console.log("err is:" + err);});//和each是有明显区别的,如果没有异步调用,和each无差别,如果有异步调用,则区别十分大async.eachSeries(objs, function(obj, callback) { doSomething(obj, function(){ callback("It's a err."); });}, function(err){ console.log("err is:" + err);});
输出
我在做A这件事!我在做B这件事!我在做C这件事!err is:undefined我在做A这件事!err is:It's a err.
看到第二个eachSeries了吧,第二个A执行了之后,抛出了异常,B,C是必然不会被执行的。
async是我日常工作中用的最多的一个工具模块了。这种帮我们理清程序和思路的工具,用熟悉一个就好。相信大家会走得更远。
1 0
- nodejs常用模块async(waterfall,each,eachSeries,whilst)
- async异步问题(waterfall、parallel、eachSeries、map、whilst)
- nodejs基于async waterfall/retry的出错重试流程设计
- async whilst使用注意
- node.js 之async.js 里waterfall模块样例
- nodejs中的async模块学习
- nodejs模块小记之--async
- Pomelo async waterfall
- async的waterfall
- nodejs async模块源代码解读与demo
- NodeJS 常用模块推荐
- NodeJS 常用模块推荐
- NodeJS 常用模块
- NodeJS 常用模块介绍
- markdown--nodejs常用模块
- NodeJS常用模块收集
- NodeJS 常用模块推荐
- NodeJS 常用模块整理
- 1.2 ASP.NET_入门_提交表单 p1
- Leetcode_13_Roman to Integer
- POJ-1211Traffic Lights
- 第13周项目 例1.3 输出平均成绩及优秀人数,不及格人数
- iOS 高级开发技巧 1.熟悉Objective-C (五) 用枚举表示状态、选项、状态码
- nodejs常用模块async(waterfall,each,eachSeries,whilst)
- OC基础总结
- 递归算法
- Android系统Recovery工作原理之使用update.zip升级过程分析
- 移动游戏开发(二)
- c++ list
- 生命周期——fragement、Activity
- gravity与layout_gravity的区别
- zoj 1414