1. 回调函数
function f1(callback) {
//...
callback();
}
function f2() {
//...
}
f1(f2);
回调函数的优点是简单、容易理解和实现,缺点是不利于代码的阅读和维护,各个部分之间高度耦合(coupling),使得程序结构混乱、流程难以追踪(尤其是多个回调函数嵌套的情况),而且每个任务只能指定一个回调函数。
2. 事件监听
另一种思路是采用时间驱动模式。 一部任务的执行不取决于代码的顺序,而取决于某个事件是否发生
f1.on('done', f2);
当f1发生done时间,就执行f2.然后对f1进行改写
function f1() {
setTimeout(fucntion (){
//...
f1.trigger('done');
},1000);
}
3. 发布/订阅
事件完全可以理解成信号,如果存在一个信号中心,某个任务执行完成,就向信号中心发布一个信号,其他人数可以向信号中心subscribe这个信号observer pattern
首先,f2向信号中心jQuery订阅done信号
jQuery.subscribe('done',f2);
然后,f1进行如下改写
function f1() {
//...
setTimeout(function (){
jQuery.publish('done');
}, 1000);
}
上面代码中,jQuery.publish('done')的意思是,f1执行完成后,向信号中心jQuery发布done信号,从而引发f2的执行。
f2完成执行后,可以取消dingyue
jQuery.unsubscribe('done',f2);
5. 异步操作的流程控制
如果有多个异步操作,就存在一个流程控制的问题:如何确定异步操作执行的顺序,以及如何保证遵守这种顺序。
function async(arg, callback){
console.log('参数为 ' + arg +' , 1秒后返回结果');
setTimeout(function () { callback(arg * 2); }, 1000);
}
5.1 串行执行
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());
网友评论