前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >jQuery进阶,$.Deferred() 延迟对象

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

作者头像
libo1106
发布2018-08-08 16:14:28
7140
发布2018-08-08 16:14:28
举报
文章被收录于专栏:Web 开发Web 开发

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

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

$.Deferred() 是什么?

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

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

代码语言:javascript
复制
$.getJSON().done(function(){
  alert('成功');
})

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

$.Deferred()有什么用?

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

代码语言:javascript
复制
/**
 * 使用Deferred前
 **/
var getImgWidth = function(){
  
  var $img = $('img');
 
  $img.on('load', function(){
    alert($(this).width());
  })
  
  $img.attr('src', 'https://www.google.com/images/srpr/logo11w.png');
 
  return $img.width();
}

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

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

代码语言:javascript
复制
/**
 * 使用Deferred后
 **/
var getImgWidth = function(){
 
  var dfd = $.Deferred();
  var $img = $('img');
 
  $img.on('load', function(){
    dfd.resolve($(this).width());
  })
  
  $img.attr('src', 'https://www.google.com/images/srpr/logo11w.png');
 
  return dfd.promise();
 
}

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

代码语言:javascript
复制
getImgWidth().done(function(width){
  alert('图片的宽度是:'+ width);
})

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

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

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

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

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

代码语言:javascript
复制
$.when(getImgWidth(), getImgWidth()).done(function(width1,width2){
  alert('第一张图片宽度:'+ width1);
  alert('第二章图片宽度:'+ width2);
});

怎样,有没发现突然晴空万里,以前的业务逻辑里面各种为了解决多个异步条件的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()方法。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-03-202,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • $.Deferred() 是什么?
  • $.Deferred()有什么用?
  • $.Deferred() 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档