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 相关文章推荐
StringTemplate遇见jQuery冲突的解决方法
Sep 22 Javascript
js实现分享到随页面滚动而滑动效果的方法
Apr 10 Javascript
PHP+jQuery实现随意拖动层并即时保存拖动位置
Apr 30 Javascript
jQuery+css实现的蓝色水平二级导航菜单效果代码
Sep 11 Javascript
jQuery如何跳转到另一个网页 就这么简单
Dec 28 Javascript
浅谈JavaScript的innerWidth与innerHeight
Oct 12 Javascript
详解vue中使用微信jssdk
Apr 19 Javascript
vue 自动化路由实现代码
Sep 03 Javascript
Vue.js组件props数据验证实现详解
Oct 19 Javascript
构建大型 Vue.js 项目的10条建议(小结)
Nov 14 Javascript
15分钟学会vue项目改造成SSR(小白教程)
Dec 17 Javascript
jQuery实现电梯导航模块
Dec 22 jQuery
简单谈谈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
新手学PHP之数据库操作详解及乱码解决!
2007/01/02 PHP
PHP中数组定义的几种方法
2013/09/01 PHP
单台服务器的PHP进程之间实现共享内存的方法
2014/06/13 PHP
对比PHP对MySQL的缓冲查询和无缓冲查询
2016/07/01 PHP
ThinkPHP3.2.3框架Memcache缓存使用方法实例总结
2019/04/15 PHP
Google韩国首页图标动画效果
2007/08/26 Javascript
基于jQuery的动态增删改查表格信息,可左键/右键提示(原创自Zjmainstay)
2012/07/31 Javascript
jQuery表单获取和失去焦点输入框提示效果的实例代码
2013/08/01 Javascript
含有CKEditor的表单如何提交
2014/01/09 Javascript
JavaScript立即执行函数的三种不同写法
2014/09/05 Javascript
浅谈jQuery 中的事件冒泡和阻止默认行为
2016/05/28 Javascript
js实现可以点击收缩或张开的悬浮窗
2017/09/18 Javascript
vue-cli项目修改文件热重载失效的解决方法
2018/09/19 Javascript
layui加载表格,绑定新增,编辑删除,查看按钮事件的例子
2019/09/06 Javascript
js回调函数仿360开机
2019/12/26 Javascript
Vue 组件注册全解析
2020/12/17 Vue.js
[43:43]完美世界DOTA2联赛PWL S2 FTD.C vs Rebirth 第一场 11.22
2020/11/24 DOTA
Python面向对象之类和对象实例详解
2018/12/10 Python
Python匿名函数及应用示例
2019/04/09 Python
python实现扫描局域网指定网段ip的方法
2019/04/16 Python
OpenCV 边缘检测
2019/07/10 Python
Python with关键字,上下文管理器,@contextmanager文件操作示例
2019/10/17 Python
django-orm F对象的使用 按照两个字段的和,乘积排序实例
2020/05/18 Python
python seaborn heatmap可视化相关性矩阵实例
2020/06/03 Python
python基于Kivy写一个图形桌面时钟程序
2021/01/28 Python
pycharm 使用anaconda为默认环境的操作
2021/02/05 Python
CSS3 box-sizing属性详解
2016/11/15 HTML / CSS
Myprotein瑞典官方网站:畅销欧洲英国运动营养品牌
2018/01/22 全球购物
建筑工程专业毕业生自荐信
2013/10/19 职场文书
外企财务年会演讲稿
2014/01/03 职场文书
先进集体事迹材料范文
2014/12/25 职场文书
公司员工手册范本
2015/05/14 职场文书
python tkinter模块的简单使用
2021/04/07 Python
代码解析React中setState同步和异步问题
2021/06/03 Javascript
《游戏王:大师决斗》将推出新卡牌包4月4日上线
2022/03/31 其他游戏
nginx访问报403错误的几种情况详解
2022/07/23 Servers