** Async ** 機(jī)制 是什么荆姆?
Async 是一個(gè)流程控制工具包,提供了直接而強(qiáng)大的異步功能映凳〉ㄍ玻基于**JavaScript **為 Node.js 設(shè)計(jì),同時(shí)也可以直接在瀏覽器中使用诈豌。
為什么要使用 ** Async ** 機(jī)制仆救?
Node.js 使用事件驅(qū)動(dòng),非阻塞I/O 模型而得以輕量和高效队询。事件發(fā)生后交由指定的程序處理派桩,處理完成后就調(diào)用事件回調(diào)函數(shù)“稣叮回調(diào)機(jī)制使 Node.js 具有了強(qiáng)大的并發(fā)處理能力铆惑,但也帶來(lái)了一系列的回調(diào)嵌套問(wèn)題, 解決回調(diào)嵌套的方法有很多, ** Async ** 就是為了解決這個(gè)問(wèn)題的
** Async ** 的功能都有什么送膳?
- 流程控制
- 集合處理
- 工具
** 本文章只討論流程控制部分员魏,其余部分且聽(tīng)下回講解 **
流程控制的方法都有什么?
流程控制常用的方法有 series
叠聋、parallel
撕阎、waterfall
、whilst
碌补、auto
series
parallel
waterfall
三種方法的具體用法
1. Async.series(tasks,callback)
用法
``series` 方法用于依次執(zhí)行多個(gè)方法虏束,一個(gè)方法執(zhí)行完畢后才會(huì)進(jìn)入下 一方法棉饶,方法之間沒(méi)有數(shù)據(jù)傳遞參數(shù)
tasks:需要執(zhí)行多個(gè)方法。tasks 可以以數(shù)組形式傳入镇匀,也可以以 object 對(duì)象形式傳入照藻。每個(gè)方法都要一個(gè)回調(diào)方法
callback(err, result):
* 作用:用于處理錯(cuò)誤或進(jìn)入下一方法。當(dāng)發(fā)生錯(cuò)誤時(shí)(即:err 參數(shù)存在時(shí))汗侵,其后的方法會(huì)跳過(guò)幸缕,錯(cuò)誤被傳入最終回調(diào)方法中
* 出錯(cuò)處理方法:出措時(shí),tasks 中拋出的錯(cuò)誤將在此方法中捕獲晰韵,錯(cuò)誤被傳入err參數(shù)
* 不出錯(cuò)處理方法:不出錯(cuò)時(shí)发乔,tasks 中回調(diào)結(jié)果將被寫(xiě)入 results 參數(shù)中,以數(shù)據(jù)或?qū)ο笮问教峁?/p>示例
//以數(shù)組形式傳入需要執(zhí)行的多個(gè)方法
async.series([
function(callback){
callback(null, 'one');
},
function(callback){
// 執(zhí)行一些操作后雪猪,callback進(jìn)入可選的最終回調(diào)方法
callback(null, 'two');
}
],
// 可選的最終回調(diào)
function(err, results){
// 當(dāng)tasks中的任一方法發(fā)生錯(cuò)誤栏尚,即回調(diào)形式為callback('錯(cuò)誤信息')時(shí)錯(cuò)誤將被傳遞給err參數(shù),未發(fā)生錯(cuò)誤err參數(shù)為空
// results中為數(shù)組中兩個(gè)方法的結(jié)果數(shù)組:['one', 'two']
});
//以object對(duì)象形式傳入需要執(zhí)行的多個(gè)方法
async.series({
one: function(callback){
// 執(zhí)行一些操作后只恨,callback進(jìn)入下一方法
callback(null, 1);
},
two: function(callback){
// 執(zhí)行一些操作后抵栈,callback進(jìn)入可選的最終回調(diào)方法
callback(null, 2);
}
},
function(err, results) {
// 當(dāng)tasks中的任一方法發(fā)生錯(cuò)誤,即回調(diào)形式為callback('錯(cuò)誤信息')時(shí)坤次,錯(cuò)誤將被傳遞給err參數(shù)古劲,未發(fā)生錯(cuò)誤err參數(shù)為空
// results中為數(shù)組中兩個(gè)方法的結(jié)果對(duì)象:{one: 1, two: 2}
});
2. Async.parallel(tasks,callback)
- 用法
parallel方法用于并行執(zhí)行多個(gè)方法,所有傳入的方法都是立即執(zhí)行缰猴,方法之間沒(méi)有數(shù)據(jù)傳遞产艾。傳遞給最終callback的數(shù)組中的數(shù)據(jù)按照tasks中聲明的順序,而不是執(zhí)行完成的順序滑绒。 - 參數(shù)
- tasks:需要執(zhí)行多個(gè)方法闷堡。tasks可以以數(shù)組形式傳入,也可以以object對(duì)象形式傳入疑故。每個(gè)方法都要一個(gè)回調(diào)方法
-
callback(err,result):
- 作用:回調(diào)方法需要提供一個(gè)err參數(shù)或是result參數(shù)杠览。當(dāng)發(fā)生錯(cuò)誤時(shí) (即:err參數(shù)存在時(shí)),所有的方法停止執(zhí)行纵势,未執(zhí)行完的方法將不會(huì)被傳遞至最終回調(diào)方法中
- 出錯(cuò)處理方法:出錯(cuò)時(shí)踱阿,tasks中拋出的錯(cuò)誤將在此方法中捕獲,錯(cuò)誤被傳入err參數(shù)
- 不出錯(cuò):不出錯(cuò)時(shí)钦铁,tasks中回調(diào)結(jié)果將被寫(xiě)入results參數(shù)中软舌,以數(shù)據(jù)或?qū)ο笮问教峁?/li>
- 示例
//以數(shù)組形式傳入需要執(zhí)行的多個(gè)方法
async.parallel([
function(callback){
// 執(zhí)行一些操作后,callback表示本方法執(zhí)行完成
callback(null, 'one');
},
function(callback){
// 執(zhí)行一些操作后牛曹,callback表示本方法執(zhí)行完成
callback(null, 'two');
}
],
// 可選的最終回調(diào)
function(err, results){
// 當(dāng)tasks中的任一方法發(fā)生錯(cuò)誤佛点,即回調(diào)形式為callback('錯(cuò)誤信息')時(shí),錯(cuò)誤將被傳遞給err參數(shù),未發(fā)生錯(cuò)誤err參數(shù)為空
// results中為數(shù)組中兩個(gè)方法的結(jié)果數(shù)組:['one', 'two'] 超营,即使第二個(gè)方法先執(zhí)行完成鸳玩,其結(jié)果也是在第一個(gè)方法結(jié)果之后
});
//以object對(duì)象形式傳入需要執(zhí)行的多個(gè)方法
async.parallel({
one: function(callback){
// 執(zhí)行一些操作后,callback表示本方法執(zhí)行完成
callback(null, 1);
},
two: function(callback){
// 執(zhí)行一些操作后演闭,callback表示本方法執(zhí)行完成
callback(null, 2);
}
},
function(err, results) {
// 當(dāng)tasks中的任一方法發(fā)生錯(cuò)誤怀喉,即回調(diào)形式為callback('錯(cuò)誤信息')時(shí),錯(cuò)誤將被傳遞給err參數(shù)船响,未發(fā)生錯(cuò)誤err參數(shù)為空
// results中為數(shù)組中兩個(gè)方法的結(jié)果對(duì)象:{one: 1, two: 2}
});
3. Async.waterfall(tasks,callback)
- 用法
waterfall方法與series方法類(lèi)似用于依次執(zhí)行多個(gè)方法,一個(gè)方法執(zhí)行完畢后才會(huì)進(jìn)入下一方法躲履,不同與series方法的是见间,waterfall之間有數(shù)據(jù)傳遞。waterfall的多個(gè)方法只能以數(shù)組形式傳入工猜,不支持object對(duì)象 - 參數(shù)
- tasks:需要執(zhí)行多個(gè)方法米诉。tasks只能以數(shù)組形式傳入。每個(gè)方法都要一個(gè)回調(diào)方法callback(err, result1, result2, ...)篷帅,用于處理錯(cuò)誤或進(jìn)入下一方法史侣。當(dāng)發(fā)生錯(cuò)誤時(shí)(即:err參數(shù)存在時(shí)),其后的方法會(huì)跳過(guò)魏身,錯(cuò)誤被傳入最終回調(diào)方法中惊橱。無(wú)錯(cuò)誤時(shí)回調(diào)參數(shù)result1, result2……將做為下一方法的輸入?yún)?shù)
- callback(err,result):
- 出錯(cuò)處理方法:出錯(cuò)時(shí),tasks中拋出的錯(cuò)誤將在此方法中捕獲箭昵,錯(cuò)誤被傳入err參數(shù)
- 不出錯(cuò):不出錯(cuò)時(shí)税朴,tasks中回調(diào)結(jié)果results為最后一個(gè)方法的回調(diào)結(jié)果
- 示例:
async.waterfall([
function(callback) {
callback(null, 'one', 'two');
},
function(arg1, arg2, callback) {
// arg1 現(xiàn)在是 'one', arg2 現(xiàn)在是 'two'
callback(null, 'three');
},
function(arg1, callback) {
// arg1 現(xiàn)在是 'three'
callback(null, 'done');
}
], function (err, result) {
//執(zhí)行的任務(wù)中方法回調(diào)err參數(shù)時(shí)家制,將被傳遞至本方法的err參數(shù)
// 參數(shù)result為最后一個(gè)方法的回調(diào)結(jié)果'done'
});
總結(jié)
series:多個(gè)任務(wù)依次執(zhí)行
parallel:多個(gè)任務(wù)并發(fā)執(zhí)行
waterfall:多個(gè)任務(wù)依次執(zhí)行正林,上一任務(wù)的輸出可做為下一任務(wù)的輸入?yún)?shù)