异步编程的4种方式
--自我整理,来自网络
1, Callback 回调函数
假设func1() 执行需要较长的时间,而func2() 等待前者的执行结果
可以将func2() 写成为 func1() 的回调函数
Function func1(callback) {
setTimeOut(function () {
// Exe a long time
Callback();
}, 1000);
}
代码变成 func1(func2)
优点: 简单,容易写
缺点: 不利于维护和阅读,高度耦合,每个任务只能指定一个回调函数
2, 事件监听
采用事件驱动模式,任务的执行不取决于代码的顺序,而取决于某个时间按是否发生。
Func1.on(“done”, func2)
Function func1(){
setTimeOut( function() {
// Exe a long time
Func1.trigger(“done”);
}, 1000);
}
优点: 容易理解,封装done,可以绑定多个事件,去耦合,有利于模块化
缺点: 整个程序变成事件驱动型,运行流程不清晰
3,发布/订阅
设置一个“信号中心”,某个任务执行完成,向信号中心“发布”(publish)一个信号,其他任务可以向信号中心“订阅”(subscribe) 这个信号,从而可以执行。这是 publish-subscribe pattern,又叫观察者模式(observer pattern)
这func2可以向信号中心 ”jQuery” 订阅”done”信号。
jQuery.subscribe(“done”, func2);
Function func1(){
setTimeOut(function (){
// Exe a long time
jQuery.publish(“done”);
}, 1000);
}
在func1 执行完之后,信号中心发布done信号,引发func2执行。
同时,func2还可以取消订阅: jQuery.unsubscribe(“done”, func2)
4, Promises对象
Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口
思想:每一个异步任何返回一个Promise对象,对象有个then方法,允许指定回调函数
Func1().then(func2)
Function func1() {
Var dfd = $.Defered();
setTimeOut( function() {
// Exe a long time
Dfd.resolve();
}, 1000);
Return dfd.promise;
}
Promise的状态:pending,fulfilled,和rejected三种状态,只有两种转换(1,pending -> fulfilled, 2, pending->rejected),每种转换只能发生一次。
Promise的then方法:then方法用于指定异步事件完成之后的回调函数。
还可以针对链式回调 Fun1().then(fuc2).then(func3)
5, Generator
除了上面的基于回调函数来实现异步的,还有Generator,最大的特点是可以产生函数的重启和暂停,Python的协程Coroutine的实现。
异步编程存在的问题:
1,异常处理问题
回调异步事件包括两个部分:异步请求和结果处理。那么对于异常,需要分开处理。
Promise实现异常的传递,好处是保证代码不被阻塞,但因为其能承担多个异步事件的原因,较难找出异步事件出现异常的原因。