由于js是单线程的,对于一些耗时操作通常采用异步执行的方式。
常用异步执行方式:
1,回调函数
假如顺序执行下面两个函数,其中fn1是比较耗时的操作。
fn1(){}; fn2(){};
这是可以考虑把fn2作为fn1的回调函数执行
fn1(callback){ setTimeout(function(){ //fn1任务 callback(); },1000) } fn1(fn2);
优点:简单,容易理解。
缺点:不利于代码的阅读和维护,各个部分直接耦合度高,流程不够清晰直观,每个任务只能绑定一个回调函数。
2,事件监听
fn1.on('done',fn2);
当fn1执行done事件fn2执行。
function fn1(){ setTimeout(function(){ //fn1任务 fn1.trigger('done'); },1000) }
fn1.trigger('done')表示fn1任务执行完成之后触发done事件,开始执行fn2任务
优点:简单,容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,有利于去耦合,容易实现 模块化。
缺点:整个程序都要变成事件驱动,运行流程不够清晰。
3,发布/订阅(观察者模式)
我们假定存在一个信号中心,某个任务执行完成就会向信号中心发布(publish)一个信号,其它任务可以向信号中心订阅(subscribe)这个信号,从而知道自己的任务何时执行。
总结:这种模式和事件监听模式类似,但是优于后者,因为我们可以通过消息中心了解存在多少个信号,每个信号有多少订阅者,从而监控程序的运行。
4,promise
promise是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。
promise的实现思想是,每个异步任务都会返回一个promise对象,该对象有一个then方法,允许指定回调函数,如下:
fn1().then(fn2);
基于jquery实现
function fn1(){ var dtd=$.Deferred(); setTimeout(function(){ //fn1任务 dtd.resolve(); },1000); return dtd.promise; }
优点:支持链式写法(fn1().then(fn2).then(fn3)),任务流程更加直观清晰。
缺点:实现和理解较为困难。
参考:http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html