jQuery的deferred对象使用详解


Posted in Javascript onSeptember 25, 2016

之前看别人的demo,发现在延迟对象被resolve时要执行的代码,有时会写在deferred.then方法里执行,有时会写在deferred.done方法里执行。

这让对延迟对象一知半解的我非常困惑,今天抽时间研究了一下下,发现:在某种环境下,两个方法的确能实现同样的效果。
这种特定的环境是怎样呢?

先看一下deferred.done的用法:

// 创建deferred对象
var dtd = $.Deferred();
 
// 解决deferred对象
dtd.resolve('finish');
// 调用done方法
dtd.done(doneCallback [, doneCallback])
// 当deferred对象被 resolve 时,执行doneCallback函数
// 参数可为一个函数、多个函数或函数数组
// 返回原来的deferred或promise对象

再看下deferred.then的用法和特性:

// 创建deferred对象
var dtd = $.Deferred();
 
// 解决deferred对象
dtd.resolve('finish');
 
// 调用then方法
deferred.then(doneFilter [, failFilter] [, progressFilter])
// then方法特性:
// 当deferred对象被resolve时,执行doneFilter函数
// 当deferred对象被reject时,执行failFilter函数
// 当dederred对象被progress时,执行progressFilter函数
// 返回值:1,返回deferred的promise对象,可修改promise传递的值( 原来resolve,reject 的返回值为a,将a修改为b,返回b,该promise的done或fail收到的返回值变为b );
// 返回值:2,在then方法内创建新的deferred对象并返回其promise
// 返回的promise对象可以链接其他的延迟对象,如done,fail,then等
// 多个then方法时,异步执行( one by one )
// 该方法会过滤掉deferred修改状态的方法,返回值deferred对象的promise 

根据以上两个方法的特性,发现:

deferred.thendeferred.done方法都可以直接收一个参数函数,且第一个参数函数都是在deferred对象在resolve时被调用。

虽说then方法可改变返回值,但在不考虑返回值且只有一个参数函数的前提下,两个方法的确可以实现一样的效果。

相比之下,done方法更纯粹吧,then方法会更复杂一些,但不能完全替代done方法,使用then方法的话,还是小心些的好。

附Deferred对象的其它方法:

// 创建延迟对象 <br>var dtd = $.Deferred();

var state = dtd.state();
// 返回deferred对象当前状态,pending / resolved / rejected
// 不接受任何参数

deferred.always( alwaysCallback [, alwaysCallback] );
// 当deferred对象被解决或拒绝时,都执行此方法
// 参数可以是一个函数,或是一个函数数组

dtd.promise( [obj] );
// 目的: 防止其他代码干涉其内部进度和状态
// 返回新的promise对象,包含可以执行的方法( done, fail, then, always, progress, state, promise ),
// 不包含修改Deferred状态的方法( resolve, reject, notify, resolveWith, rejectWith, nodifyWith )
// 需返回deferred对象时,建议返回deferred.promise()

dtd.resolve( [args] )
// 解决deferred对象,调用所有doneCallback函数
// doneCallback可通过then方法中第一个参数设置,也可通过dtd.done( doneCallback )添加
// 参数将传递给doneCallback。参数可选
// 只有deferred对象的创建者才可以调用的方法
// doneCallback中this为deferred或promise对象
// doneCallback只接收一个参数

dtd.resolveWith( context [,args] )
// 解决deferred对象,调用所有doneCallback函数
// 参数:第一个参数为上下文即this对象,doneCallback的this将被修改;第二个参数为数组
// doneCallback中this为调用resolveWith方法的上下文
// doneCallback接收参数个数为该方法第二个参数数组的长度
// 与resolve方法的区别在于,将改变doneCallback函数的this指向

dtd.reject( [args] )
// 拒绝deferred对象,调用所有failCallback函数
// failCallback可通过then方法中第二个参数设置,也可通过dtd.fail( failCallback )添加
// 参数将传递给failCallback。参数可选
// 只有deferred对象的创建者才可以调用的方法
// failCallback中this为deferred或promise对象
// failCallback只接收一个参数

dtd.rejectWith(context, [args] )
// 解决deferred对象,调用所有failCallback函数
// 参数:第一个参数为上下文即this对象,failCallback的this将被修改;第二个参数为数组
// failCallback中this为调用rejectWith方法的上下文
// failCallback接收参数个数为该方法第二个参数数组的长度
// 与resolve方法的区别在于,将改变failCallback函数的this指向

dtd.notify( [args] )
// deferred进行处理时,调用所有的progressCallback函数
// progressCallback可通过then方法中的第3个参数设置,也可以通过deferred.progress( progressCallback )添加
// 通常此方法只能被deferred对象的创建者调用,可通过deferred.promise或then过滤此方法
// 参数可不写。若写有参数,建议为字符串或可返回字符串的函数
// 当deferred进入 resolved 或rejected状态后,再调用notify方法,progressCallback将不再被执行

dtd.notifyWith(context, [args] )
// deferred进行处理时, 调用所有progressCallback函数
// 参数:第一个参数为上下文即this对象,progressCallback的this将被修改;第二个参数为数组
// progressCallback中this为调用rejectWith方法的上下文
// progressCallback接收参数个数为该方法第二个参数数组的长度
// 与resolve方法的区别在于,将改变progressCallback函数的this指向
// 当deferred进入 resolved 或rejected状态后,再调用notifyWith方法,progressCallback将不再被执行
Javascript 相关文章推荐
jQuery Flash/MP3/Video多媒体插件
Jan 18 Javascript
在jquery boxy中添加百度地图坐标拾取注意流程
Apr 03 Javascript
jQuery UI插件自定义confirm确认框的方法
Mar 20 Javascript
JavaScript中数据结构与算法(五):经典KMP算法
Jun 19 Javascript
基于Bootstrap实现Material Design风格表单插件 附源码下载
Apr 18 Javascript
微信JS-SDK坐标位置如何转换为百度地图坐标
Jul 04 Javascript
js简单时间比较的方法
Aug 02 Javascript
Bootstrap基本组件学习笔记之列表组(11)
Dec 07 Javascript
jQuery基本筛选选择器实例代码
Feb 06 Javascript
详解Vue-cli 创建的项目如何跨域请求
May 18 Javascript
layui layer select 选择被遮挡的解决方法
Sep 21 Javascript
vue视频播放暂停代码
Nov 08 Javascript
简单谈谈Vue 模板各类数据绑定
Sep 25 #Javascript
D3.js实现直方图的方法详解
Sep 25 #Javascript
关于JS中二维数组的声明方法
Sep 24 #Javascript
js日期相关函数dateAdd,dateDiff,dateFormat等介绍
Sep 24 #Javascript
浅谈JS中的!=、== 、!==、===的用法和区别
Sep 24 #Javascript
让DIV的滚动条自动滚动到最底部的3种方法(推荐)
Sep 24 #Javascript
浅谈js常用内置方法和对象
Sep 24 #Javascript
You might like
全国FM电台频率大全 - 3 河北省
2020/03/11 无线电
基于PHP常用字符串的总结(待续)
2013/06/07 PHP
php第一次无法获取cookie问题处理
2014/12/15 PHP
深入研究PHP中的preg_replace和代码执行
2018/08/15 PHP
PHP中localeconv()函数的用法
2019/03/26 PHP
window.onload 加载完毕的问题及解决方案(下)
2009/07/09 Javascript
IE事件对象(The Internet Explorer Event Object)
2012/06/27 Javascript
利用JS延迟加载百度分享代码,提高网页速度
2013/07/01 Javascript
JavaScript设计模式之单例模式实例
2014/09/24 Javascript
JS实现的5级联动Select下拉选择框实例
2015/08/17 Javascript
一些实用性较高的js方法
2016/04/19 Javascript
jQuery常用样式操作实例分析(获取、设置、追加、删除、判断等)
2016/09/08 Javascript
简单理解vue中Props属性
2016/10/27 Javascript
利用node.js爬取指定排名网站的JS引用库详解
2017/07/25 Javascript
详解react-native-fs插件的使用以及遇到的坑
2017/09/12 Javascript
JS实现带动画的回到顶部效果
2017/12/28 Javascript
js jquery 获取某一元素到浏览器顶端的距离实现方法
2018/09/05 jQuery
如何在微信小程序中实现Mixins方案
2019/06/20 Javascript
解决vue.js提交数组时出现数组下标的问题
2019/11/05 Javascript
JavaScript 正则应用详解【模式、欲查、反向引用等】
2020/05/13 Javascript
[04:28]DOTA2亚洲邀请赛小组赛第五日 TOP10精彩集锦
2015/02/03 DOTA
python的常见命令注入威胁
2013/02/18 Python
django 做 migrate 时 表已存在的处理方法
2019/08/31 Python
python字典setdefault方法和get方法使用实例
2019/12/25 Python
Spark处理数据排序问题如何避免OOM
2020/05/21 Python
Python3爬虫里关于识别微博宫格验证码的知识点详解
2020/07/30 Python
HTML5上传文件显示进度的实现代码
2012/08/30 HTML / CSS
HTML5自定义视频播放器源码
2020/01/06 HTML / CSS
LODI女鞋在线商店:阿利坎特的鞋类品牌
2019/02/15 全球购物
数学教学随笔感言
2014/02/17 职场文书
化工操作工岗位职责
2014/04/29 职场文书
学校党委干部个人对照检查材料思想汇报
2014/10/09 职场文书
签字仪式主持词
2015/07/03 职场文书
业务员管理制度范本
2015/08/06 职场文书
百年校庆宣传标语口号
2015/12/26 职场文书
详细介绍Java中的CyclicBarrier
2022/04/13 Java/Android