JavaScript异步编程(2)- 先驱者:jsDeferred

430 查看

JavaScript当前有众多实现异步编程的方式,最为耀眼的就是ECMAScript 6规范中的Promise对象,它来自于CommonJS小组的努力:Promise/A+规范。

研究javascript的异步编程,jsDeferred也是有必要探索的:因为Promise/A+规范的制定基本上是奠定在jsDeferred上,它是javascript异步编程中里程碑式的作品。jsDeferred自身的实现也是非常有意思的。

本文将探讨项目jsDeferred的模型,带我们感受一个不一样的异步编程体验和实现。

本文内容如下:

  • jsDeferred和Promise/A+
  • jsDeferred的工作模型
  • jsDeferred API
  • 参考和引用

jsDeferred和Promise/A+

在上一篇文章《JavaScript异步编程(1)- ECMAScript 6的Promise对象》中,我们讨论了ECMAScript 6的Promise对象,这一篇我们来看javascript异步编程的先驱者——jsDeferred。

jsDeferred是日本javascript高手geek cho45受MochiKit.Async.Deferred模块启发在2007年开发(07年就在玩这个了…)的一个异步执行类库。我们将jsDeferred的原型和Promise/A+规范译文戳这里)进行对比(来自^_^肥仔John的《JS魔法堂:jsDeferred源码剖析》):

Promise/A+

  • Promise是基于状态的
  • 状态标识:pending(初始状态)、fulfilled(成功状态)和rejected(失败状态)。
  • 状态为单方向移动“pending->fulfilled”,”pending->rejected”。
  • 由于存在状态标识,所以支持晚事件处理的晚绑定。

jsDeferred

  • jsDeferred是基于事件的,并没有状态标识
  • 实例的成功/失败事件是基于事件触发而被调用
  • 因为没有状态标识,所以可以多次触发成功/失败事件
  • 不支持晚绑定

jsDeferred的工作模型

下面一张图粗略演示了jsDeferred的工作模型。

下面涉及到jsDeferred的源码,对于第一次接触的童鞋请直接拉到API一节(下一节),读完了API再来看这里。

jsDeferred第一次调用next有着不同的处理,jsDeferred在第一次调用next()的时候,会立即异步执行这个回调函数——而这个挂起异步,则视当前的环境(如浏览器最佳环境)选择最优的异步挂起方案,例如现代浏览器下会通过创建Image对象的方式来进行异步挂起,摘录源码如下:

Deferred对象的静态方法 – Deferred.next()源码:

我们务必要理清Deferred.next()和Deferred.prototype.next(),这是两种不同的东西:

  • Deferred.next()的职责是压入异步的代码,并立即异步执行的。
  • Deferred.prototype.next()是从上一个Deferred对象链中构建的Deferred。当没有上一个Deferred链的时候,它并不会执行next()中压入的函数,它的执行继承于上一个Deferred触发的事件或自身事件的触发[ call / fail ]。

摘录源码如下: