Node.js异步流程控制:async模块核心方法详解

作者:慢半拍时间:2026-10-22 05:58:03浏览:571

本文详细介绍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); 
}) 

运行结果:

Node.js异步流程控制:async模块核心方法详解

若中途发生错误,错误将传递至回调函数,后续任务停止执行。


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); 
}) 

运行结果:

Node.js异步流程控制:async模块核心方法详解

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方法"); 
}) 

运行结果:

Node.js异步流程控制:async模块核心方法详解

三个函数分别延迟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方法"); 
}) 

运行结果:

Node.js异步流程控制:async模块核心方法详解

数据流传递与并发限制

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方法"); 
}) 

执行结果:

Node.js异步流程控制:async模块核心方法详解 

若中途出现错误,后续函数不再执行,之前执行的结果和错误信息直接传至最终回调函数。


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方法"); 
}) 

运行结果:

Node.js异步流程控制:async模块核心方法详解

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方法"); 
}) 

运行结果:

Node.js异步流程控制:async模块核心方法详解

三个函数延迟分别为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方法"); 
}); 

运行结果:

Node.js异步流程控制:async模块核心方法详解

总耗时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结束'); 
}); 

运行结果:

Node.js异步流程控制:async模块核心方法详解

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); 
}); 

运行结果:

Node.js异步流程控制:async模块核心方法详解

函数组合与总结

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方法"); 
}) 

运行结果:

Node.js异步流程控制:async模块核心方法详解

相当于 var m=2; (m*2+3)*5 =35;。

在我的项目开发中waterfall用的最多。

更多方法详情 : https://www.npmjs.com/package/async

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章