Node.js异步流程控制:async模块核心方法详解
本文详细介绍Node.js中async模块的常用异步控制方法。通过series、parallel、waterfall、parallelLimit、auto、循环控制及compose等函数,解决嵌套回调与数据传递问题,帮助开发者高效处理复杂异步逻辑。
Node.js异步流程控制:async模块核心方法详解
近期在研究Node.js开发,重点梳理了async模块的相关知识点。由于涉及内容较多,特此整理笔记以便回顾。
async模块旨在解决回调地狱(嵌套金字塔)及异步流程控制问题。以下将介绍其常用方法。
通过npm安装async模块后,使用var async = require('async');即可引入使用。
顺序执行与并行控制
1. series(tasks,[callback])
该方法使多个任务按顺序依次执行,任务间无数据交互。
var task1 =function(callback){
console.log("task1");
callback(null,"task1")
}
var task2 =function(callback){
console.log("task2");
callback(null,"task2")
}
var task3 =function(callback){
console.log("task3");
callback(null,"task3")
}
async.series([task1,task2,task3],function(err,result){
console.log("series");
if (err) {
console.log(err);
}
console.log(result);
})
运行结果:

若中途发生错误,错误将传递至回调函数,后续任务停止执行。
var task1 =function(callback){
console.log("task1");
callback(null,"task1")
}
var task2 =function(callback){
console.log("task2");
callback("err","task2")
}
var task3 =function(callback){
console.log("task3");
callback(null,"task3")
}
async.series([task1,task2,task3],function(err,result){
console.log("series");
if (err) {
console.log(err);
}
console.log(result);
})
运行结果:

2.parallel(tasks,[callback])
多个函数并行执行,互不等待。
var task1 =function(callback){
console.log("task1");
setTimeout(function(){
callback(null,"task1")
},5000);
}
var task2 =function(callback){
console.log("task2");
setTimeout(function(){
callback(null,"task2")
},1000);
}
var task3 =function(callback){
console.log("task3");
setTimeout(function(){
callback(null,"task3")
},3000);
}
console.time("parallel方法");
async.parallel([task1,task2,task3],function(err,result){
console.log("parallel");
if (err) {
console.log(err);
}
console.log(result);
console.timeEnd("parallel方法");
})
运行结果:

三个函数分别延迟5000ms、1000ms、3000ms,最终耗时5000ms即执行完毕。
若中途出错,立即将错误和已获取的值传至最终回调函数,未执行完毕的函数不再执行,但仍需占用位置。
var task1 =function(callback){
console.log("task1");
setTimeout(function(){
callback(null,"task1")
},5000);
}
var task2 =function(callback){
console.log("task2");
setTimeout(function(){
callback("errmessage","task2")
},3000);
}
var task3 =function(callback){
console.log("task3");
setTimeout(function(){
callback(null,"task3")
},1000);
}
console.time("parallel方法");
async.parallel([task1,task2,task3],function(err,result){
console.log("parallel");
if (err) {
console.log(err);
}
console.log(result);
console.timeEnd("parallel方法");
})
运行结果:

数据流传递与并发限制
3.waterfall(tasks,[callback]) :瀑布流
依次执行,前一个函数的输出作为后一个函数的输入。
var task1 =function(callback){
console.log("task1");
callback(null,"11")
}
var task2 =function(q,callback){
console.log("task2");
console.log("task1函数传入的值: "+q);
callback(null,"22")
}
var task3 =function(q,callback){
console.log("task3");
console.log("task2函数传入的值: "+q);
callback(null,"33")
}
console.time("waterfall方法");
async.waterfall([task1,task2,task3],function(err,result){
console.log("waterfall");
if (err) {
console.log(err);
}
console.log("result : "+result);
console.timeEnd("waterfall方法");
})
执行结果:
若中途出现错误,后续函数不再执行,之前执行的结果和错误信息直接传至最终回调函数。
var task1 =function(callback){
console.log("task1");
callback(null,"11")
}
var task2 =function(q,callback){
console.log("task2");
console.log("task1函数传入的值: "+q);
callback("errmessage","22")
}
var task3 =function(q,callback){
console.log("task3");
console.log("task2函数传入的值: "+q);
callback(null,"33")
}
console.time("waterfall方法");
async.waterfall([task1,task2,task3],function(err,result){
console.log("waterfall");
if (err) {
console.log(err);
}
console.log("result : "+result);
console.timeEnd("waterfall方法");
})
运行结果:

4.parallelLimit(tasks,limit,[callback])
与parallel类似,但通过limit参数限制同时并发执行的数量,避免无限并发。
var task1 =function(callback){
console.log("task1");
setTimeout(function(){
callback(null,"task1")
},5000);
}
var task2 =function(callback){
console.log("task2");
setTimeout(function(){
callback(null,"task2")
},3000);
}
var task3 =function(callback){
console.log("task3");
setTimeout(function(){
callback(null,"task3")
},4000);
}
console.time("parallelLimit方法");
async.parallelLimit([task1,task2,task3], 2, function(err,result){
console.log("parallelLimit");
if (err) {
console.log(err);
}
console.log(result);
console.timeEnd("parallelLimit方法");
})
运行结果:

三个函数延迟分别为5000ms、3000ms、4000ms,总耗时7000ms。
首先执行函数1和函数2。
3秒后函数2执行完毕,此时启动函数3。
5秒后函数1执行完毕,此时函数3还需2秒。
7秒后函数3执行完毕。
自动依赖与循环控制
5.auto(tasks,[callback])
支持多个函数间的数据交互,部分并行、部分依次执行。
console.time("auto方法");
async.auto({
task1: function(callback){
console.log("tsak1");
setTimeout(function(){
callback(null, 'task11', 'task12');
},2000);
},
task2: function(callback){
console.log('task2');
setTimeout(function(){
callback(null, 'task2');
},3000);
},
task3: ['task1', 'task2', function(callback, results){
console.log('task3');
console.log('task1和task2运行结果: ',results);
setTimeout(function(){
callback(null, 'task3');
},1000);
}],
task4: ['task3', function(callback, results){
console.log('task4');
console.log('task1,task2,task3运行结果: ',results);
setTimeout(function(){
callback(null, {'task41':results.task3, 'task42':'task42'});
},1000);
}]
}, function(err, results) {
console.log('err :', err);
console.log('最终results : ', results);
console.timeEnd("auto方法");
});
运行结果:

总耗时5秒。
函数1和函数2并行执行,耗时3秒。
函数1和函数2完成后,函数3和函数4依次执行,共计5秒。
6.whilst(test,fn,[callback])
类似while循环。无论fn内是同步还是异步操作,都会执行完上一次循环才进入下一次。对异步循环处理很有帮助,test为条件,为true时执行fn里的方法。
var datalist = [{number:10},{number:20},{number:30},{number:40},{number:50}];
var count = 0;
var test = function () {
return count<datalist.length;
};
var fn = function(callback){
console.log(datalist[count].number);
setTimeout(function () {
count++;
callback();
},1000)
};
async.whilst(test,fn,function(err){
if(err){
console.log(err);
}
console.log('whilst结束');
});
运行结果:

7.doWhilst
与whilst类似,相当于do-while结构。首先执行一次fn,再进行判断。与whilst相比,仅交换了fn和test的位置。
until与whilst相反,当test判断为false时执行fn里的方法,为true时跳出。
doUntil与doWhilst相反。
8.forever(fn,errback)
forever实现无限循环,仅当中途出现错误时才会停止。
var count = 0;
async.forever(function(callback){
console.log(count);
count++;
if (count>10) {
callback("errmessage");
return;
}
setTimeout(function () {
callback();
},1000)
},
function(err){
console.log(err);
});
运行结果:

函数组合与总结
9.compose(fn1,fn2,fn3...)
该方法创建异步集合函数,执行顺序为倒序。前一个fn的输出是后一个fn的输入,存在数据交互。
var task1 =function(m,callback){
console.log("task1");
setTimeout(function(){
callback(null,m*2)
},1000);
}
var task2 =function(m,callback){
console.log("task2");
setTimeout(function(){
callback(null,m+3)
},1000);
}
var task3 =function(m,callback){
console.log("task3");
setTimeout(function(){
callback(null,m*5)
},1000);
}
console.time("compose方法");
var com = async.compose(task3,task2,task1);
com(2,function(err,result){
if (err) {
console.log(err);
}
console.log(result);
console.timeEnd("compose方法");
})
运行结果:

相当于 var m=2; (m*2+3)*5 =35;。
在我的项目开发中waterfall用的最多。
更多方法详情 : https://www.npmjs.com/package/async
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
Java和JavaScript名字像但没关系?详解两者及HTML的技术分工
2026-11-03 20:24:10
Node.js 中 CommonJS 与 ES Modules 模块规范的区别及使用
2026-11-03 15:35:13
先学JS还是先学Java?全栈开发视角的学习路径规划
2026-11-03 13:35:26
解决Node.js安装后提示“node不是内部或外部命令”
2026-11-03 08:39:43
生产环境升级 Node.js 的风险评估与 LTS 版本选择
2026-11-02 10:30:14
