jQuery进阶,$.Deferred() 延迟对象

JS里面有大量的异步方法,写着写着,代码就会变得>>。多层嵌套的回调,很影响后续代码的维护,也许今天你还记得这块回调逻辑,明天你就很有可能被这回调姿势给坑了。

那么,今天就介绍一种抹平回调的方法,jQuery.Deferred。

$.Deferred() 是什么?

$.Deferred() 从字面上理解,就是一个延迟对象。它是jQuery出的,为了解决回调嵌套,方便开发者的一种函数。

好像好高深,其实我们很早就有接触,并经常在用到。

jQuery的$.ajax()本身就支持Deferred,它可以链式补上 .done()  .fail() 等方法来处理不同状态的结果。

$.Deferred()有什么用?

例如动态获取一张图片的宽度

当调用 getImgWidth() 的时候,其返回值没法获取到正确的宽度,而随后当图片加载完成触发load事件后,alert出来的宽度才是正常的。

那么,我们改怎么修改这个方法呢?

这段升级后的函数,再获取的宽度的时候,就可以使用如下方法轻松获得

看完这段改造后的代码,也许有人会说,这个作用不大呀,和直接给 getImgWidth(callback) 加多一个回调函数没什么区别。

嗯,从这里来看,貌似是这样,但是,当我们要同时处理多个异步的时候,$.Deffered()的威力就体现出来了。

比如,需求是同时加载完两张图片,得到两个宽度之后,才开始执行后续逻辑。

传统的回调要怎么写?反正我是晕了。

用$.Deferred()就很简单,getImgWidth()的定义不变,使用$.when()方法来处理同时完成的事件。

怎样,有没发现突然晴空万里,以前的业务逻辑里面各种为了解决多个异步条件的setTimeout()是不是瞬间变得很没用。

$.Deferred() 小结

拥抱Deferred,抛弃那些不可控的setTimeout()吧。

最后引用阮一峰的《jQuery的deferred对象详解》里面的小结吧:

  • $.Deferred() 生成一个deferred对象。
  • deferred.done() 指定操作成功时的回调函数
  • deferred.fail() 指定操作失败时的回调函数
  • deferred.promise() 没有参数时,返回一个新的deferred对象,该对象的运行状态无法被改变;接受参数时,作用为在参数对象上部署deferred接口。
  • deferred.resolve() 手动改变deferred对象的运行状态为”已完成”,从而立即触发done()方法。
  • deferred.reject() 这个方法与deferred.resolve()正好相反,调用后将deferred对象的运行状态变为”已失败”,从而立即触发fail()方法。
  • $.when() 为多个操作指定回调函数。
  • deferred.then() 有时为了省事,可以把done()和fail()合在一起写,这就是then()方法。