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方法");
})
運作結果:
3個函數分别延遲5000ms,1000ms,3000ms 結果5000ms就執行完畢.
如果中途出錯,則立即将err和值傳到最終的回調函數,其他未執行完畢的函數将不再執行,但是要占一個位置
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