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 相关文章推荐
js tab 选项卡
Apr 26 Javascript
String.prototype实现的一些javascript函数介绍
Nov 22 Javascript
JS实现两个大数(整数)相乘
Apr 28 Javascript
javascript设计模式之中介者模式Mediator
Dec 30 Javascript
嵌入式iframe子页面与父页面js通信的方法
Jan 20 Javascript
JavaScript中清空数组的方法总结
Dec 02 Javascript
Vue2.0 axios前后端登陆拦截器(实例讲解)
Oct 27 Javascript
浅谈es6 javascript的map数据结构
Dec 14 Javascript
Angular使用cli生成自定义文件、组件的方法
Sep 04 Javascript
jQuery pjax 应用简单示例
Sep 20 jQuery
详解vue-cli项目开发/生产环境代理实现跨域请求
Jul 23 Javascript
JavaScript实现HSL拾色器
May 21 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
从零开始学YII2框架(一)通过Composer安装Yii2框架
2014/08/20 PHP
laravel-admin 实现在指定的相册下添加照片
2019/10/21 PHP
关于__defineGetter__ 和__defineSetter__的说明
2007/05/12 Javascript
HTML 自动伸缩的表格Table js实现
2009/04/01 Javascript
高性能web开发 如何加载JS,JS应该放在什么位置?
2010/05/14 Javascript
JavaScript对IE操作的经典代码(推荐)
2014/03/10 Javascript
jquery实现在页面加载的时自动为日期插件添加当前日期
2014/08/20 Javascript
JavaScript中的parse()方法使用简介
2015/06/12 Javascript
jQuery validate插件实现ajax验证重复的2种方法
2016/01/22 Javascript
探讨:JavaScript ECAMScript5 新特性之get/set访问器
2016/05/05 Javascript
JavaScript 数组中最大最小值
2016/06/05 Javascript
BootStrap Progressbar 实现大文件上传的进度条的实例代码
2016/06/27 Javascript
基于js实现checkbox批量选中操作
2016/11/22 Javascript
Angular.js与node.js项目里用cookie校验账户登录详解
2017/02/22 Javascript
使用bootstrap-paginator.js 分页来进行ajax 异步分页请求示例
2017/03/09 Javascript
js实现1,2,3,5数字按照概率生成
2017/09/12 Javascript
重学 JS:为啥 await 不能用在 forEach 中详解
2019/04/15 Javascript
node.js中process进程的概念和child_process子进程模块的使用方法示例
2020/02/11 Javascript
Pycharm学习教程(2) 代码风格
2017/05/02 Python
对numpy 数组和矩阵的乘法的进一步理解
2018/04/04 Python
使用Python进行体育竞技分析(预测球队成绩)
2019/05/16 Python
快速解决vue.js 模板和jinja 模板冲突的问题
2019/07/26 Python
用python生成与调用cntk模型代码演示方法
2019/08/26 Python
python多继承(钻石继承)问题和解决方法简单示例
2019/10/21 Python
详解Python在使用JSON时需要注意的编码问题
2019/12/06 Python
python异常处理之try finally不报错的原因
2020/05/18 Python
CSS3打造磨砂玻璃背景效果
2016/09/28 HTML / CSS
100%植物性、有机、即食餐:Sakara Life
2018/10/25 全球购物
应用艺术毕业生的自我评价
2013/12/04 职场文书
公司出纳岗位职责
2013/12/07 职场文书
体育馆的标语
2014/06/24 职场文书
2014大学校园光棍节活动策划书
2014/09/29 职场文书
合同权益转让协议书模板
2014/11/18 职场文书
大雁塔导游词
2015/02/04 职场文书
《金色的草地》教学反思
2016/02/17 职场文书
Python中request的基本使用解决乱码问题
2022/04/12 Python