异步编程的方法

“异步模式”:每一个任务有一个或多个回调函数,前一个任务结束后,不是执行下一个任务,而是执行这个回调函数。后一个任务不等前一个任务结束就执行。

异步编程的四种方法:1.回调函数2.事件监听3.发布- 订阅者模式4.Promise对象

一、回调函数

假定有两个函数f1和f2,后者等待前者的执行结果

f1();

f2();

如果f1是一个非常耗线程的任务,考虑改写f1,把f2写成f1的回调函数

function f1(callback) {

   setTimeout({

    function () {

    //执行f1的代码

   callback();

}

},3000)

}

f1(f2);

优点:简单,容易理解。缺点:各个部分之间高度耦合,流程复杂,每一个任务只能指定一个回调函数

二、事件监听

另一个思路就是采用事件驱动模式。任务的执行不取决代码的顺序,而是取决于某个事件是否发生。

首先:给f1绑定事件

f1.on("done",f2)

然后:改写f1函数

function  f1() {

setTimeout(function () {

    //执行f1的代码

  f1.trigger("done")

},3000)

}

优点:可以绑定多个事件,每个事件可绑定多个回调函数,可以去耦合,有利于模块化。缺点:整个程序都要变成事件驱动型,运行流程会变的非常不清晰。

三、发布/订阅者模式

我们假定存在一个“信号中心”,某个任务执行完成后就向“信号中心”发布一个信号,其它任务可以向“信号中心”订阅这个“信号”,从而知道自己什么时候开始执行。

首先,f2向“信号中心”JQuery订阅“done”信号

jquery.subscribe("done",f2)

然后,改写f1

function f1 () {

setTimeout(function () {

   //执行f1的代码

    jquery.publish("done")

},3000)

}

我们可以通过查看“消息中心”,了解存在有多少个信号,每个信号有多少个订阅者,从而监控程序的运行。

四、Promise对象

简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:

  f1().then(f2);

f1要进行如下改写(这里使用的是jQuery的实现):

  function f1(){

    var dfd = $.Deferred();

    setTimeout(function () {

      // f1的任务代码

      dfd.resolve();

    }, 500);

    return dfd.promise;

  }

这样写的优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。

比如,指定多个回调函数:

  f1().then(f2).then(f3);

再比如,指定发生错误时的回调函数:

  f1().then(f2).fail(f3);

而且,它还有一个前面三种方法都没有的好处:如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。这种方法的缺点就是编写和理解,都相对比较难。

 详细讲解见:http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html

猜你喜欢

转载自blog.csdn.net/mrhuanhuan/article/details/82936344