1. 回調(diào)函數(shù)
function f1(callback) {
//...
callback();
}
function f2() {
//...
}
f1(f2);
回調(diào)函數(shù)的優(yōu)點是簡單、容易理解和實現(xiàn),缺點是不利于代碼的閱讀和維護,各個部分之間高度耦合(coupling),使得程序結(jié)構(gòu)混亂、流程難以追蹤(尤其是多個回調(diào)函數(shù)嵌套的情況),而且每個任務(wù)只能指定一個回調(diào)函數(shù)。
2. 事件監(jiān)聽
另一種思路是采用時間驅(qū)動模式。 一部任務(wù)的執(zhí)行不取決于代碼的順序,而取決于某個事件是否發(fā)生
f1.on('done', f2);
當(dāng)f1發(fā)生done時間,就執(zhí)行f2.然后對f1進行改寫
function f1() {
setTimeout(fucntion (){
//...
f1.trigger('done');
},1000);
}
3. 發(fā)布/訂閱
事件完全可以理解成信號,如果存在一個信號中心,某個任務(wù)執(zhí)行完成,就向信號中心發(fā)布一個信號,其他人數(shù)可以向信號中心subscribe這個信號observer pattern
首先,f2向信號中心jQuery訂閱done信號
jQuery.subscribe('done',f2);
然后,f1進行如下改寫
function f1() {
//...
setTimeout(function (){
jQuery.publish('done');
}, 1000);
}
上面代碼中,jQuery.publish('done')的意思是,f1執(zhí)行完成后,向信號中心jQuery發(fā)布done信號,從而引發(fā)f2的執(zhí)行。
f2完成執(zhí)行后,可以取消dingyue
jQuery.unsubscribe('done',f2);
5. 異步操作的流程控制
如果有多個異步操作,就存在一個流程控制的問題:如何確定異步操作執(zhí)行的順序,以及如何保證遵守這種順序。
function async(arg, callback){
console.log('參數(shù)為 ' + arg +' , 1秒后返回結(jié)果');
setTimeout(function () { callback(arg * 2); }, 1000);
}
5.1 串行執(zhí)行
var items = [1,2,3,4,5,6];
var results = [];
function async(arg, callback) {
console.log(arg);
setTimeout(function() {callback(arg*2);},1000);
}
function final(value){
console.log('done:',value);
}
function series(item) {
if(item){
async(item, function(result){
results.push(result);
return series(item.shift());
});
}else {
return final(results[results.length -1]);
}
}
series(item.shift());