jQuery中deferred对象使用方法详解


Posted in Javascript onJuly 14, 2016

在jquery1.5之后的版本中,加入了一个deferred对象,也就是延迟对象,用来处理未来某一时间点发生的回调函数。同时,还改写了ajax方法,现在的ajax方法返回的是一个deferred对象。
那就来看看deferred对象的用法。
1.ajax的链式回调 

// ajax方法返回的是一个deferred对象,可以直接使用链式写法
$.ajax('test.json').done(function(resp){
 // done 相当于success回调,其中默认的参数为success回调的参数
 alert('success');
}).fail(function(){
 // fail 相当于error回调
 alert('error');
});

还可以同时写多个回调,会按照顺序依次执行 

$.ajax('test.json').done(function(resp){
 // done 相当于success回调,其中默认的参数为success回调的参数
 alert('success');
}).done(function(){
 // do something...
}).done(function(){
 // do something...
});

deferred对象还有一个then方法,其实它是一个整合done和fail的方法,它接受一到两个参数,如果有两个参数,那么第一个就是done方法的回调函数,第二个是fail方法的回调函数。如果只有一个参数,那就是done方法的回调函数。 

var success = function(){
 alert('success'); 
};

var error = function(){
 alert('error');
};

// 两个参数
$.ajax('test.json').then(success, error);

// 一个参数
$.ajax('test.json').then(success);

jQuery还提供了一个$.when(deferreds)的方法来执行一个或多个延迟对象的回调函数,当它的参数是延迟对象时,它会在所有延迟对象代表的异步执行完后再执行相应的回调函数 

$.when($.ajax('test.json'), $.ajax('demo.json')) .done(function(){
 alert('success'); 
}).fail(function(){
 alert('error');
});

很好理解,只有当所有异步都成功时,才会执行done方法中的回调,否则会执行fail方法中的回调,同样好理解的是的done方法中回调函数的默认参数数量则和when方法参数数量相同。
而如果when方法中传入的只是普通对象,不是deferred对象时,会立即执行done方法中的回调,回调函数的默认参数为传入when方法的对象本身。

// 当传入when方法的参数只是普通对象时
$.when({test: 'test'}).done(function(resp){
 console.log(resp.test); // 'test' 
}).fail(function(){
 // 由于传入的对象不是deferred对象,那么就不会调用fail中的回调了 
})

当你需要两个甚至更多的异步结束后才调用回调函数,同时这些异步ajax可能还需要修改传输方式type或者传数据data时,代码就显得很乱,可读性很差。 
所以就可以对ajax进行再次封装,提高代码可读性 

var ajax = function(url, type, param){
 return $.ajax({
 url: url,
 type: type,
 data: param || {} 
 }); 
};

ajax('test.json').done(function(resp){
 alert('success');
}).fail(function(){
 alert('error');
});

接者学习,漏了一个always()方法,参数也是回调函数,与done和fail不同的是,无论任何情况都执行always方法中的回调。
deferred对象不光可以用在jquery的ajax方法中,他提供了一系列的接口,使它的通用型大大提高。
比如有这样一个耗时比较久的方法

function a(){
 function b(){
 alert('start');
 } 
 setTimeout(b, 3000); 
}

如果要在这个方法之后执行某个回调,就不能用$.when()了,因为当$.when()的参数不为deferred对象是会直接调用done或者always中的回调函数。
这个时候就要使用deferred对象的其他方法了,还是上面的方法,做一些改写 

function a(){
 var def = $.Deferred(); // 创建deferred对象 
 function b(){
 alert('start');
 def.resolve(); // 改变deferred对象的状态
 } 
 setTimeout(b, 3000); 
 return def;
}

$.when(a()).done(function(){
 alert("It's callback");
});

分析一下:
 1). $.Deferred()方法会创建一个deferred对象
 2). def.resolve()会改变deferred对象的状态,deferred对象有三种状态,未完成,成功,失败。
 它有resolve()和reject()两个方法,resolve方法可以把对象状态改为成功,reject方法可以把状态改为失败。
 又有以上的写法会出现问题,返回的deferred对象可以被外部改变状态,所以还提供了一个promise()方法,这个方法会在deferred对象的基础上返回一个新的deferred对象,不同的是,返回的对象只存在可被观察到状态,而不具备可改变其状态的方法,类似返回了一个只读的deferred对象。
 所以同样的例子可以改写成这样 

function a(){
 var def = $.Deferred(); // 创建deferred对象 
 function b(){
 alert('start');
 def.resolve(); // 改变deferred对象的状态
 } 
 setTimeout(b, 3000); 
 return def.promise();
}

$.when(a().reject()).done(function(){ // reject()方法无效
 alert("It's callback");
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JQuery 插件模板 制作jquery插件的朋友可以参考下
Mar 17 Javascript
javascript淡入淡出效果的实现思路
Mar 31 Javascript
caller和callee的区别介绍及演示结果
Mar 10 Javascript
轻松实现jquery手风琴效果
Jan 14 Javascript
微信小程序开发实战教程之手势解锁
Nov 18 Javascript
微信小程序 支付功能实现PHP实例详解
May 12 Javascript
微信小程序 http请求的session管理
Jun 07 Javascript
JavaScript实现移动端页面按手机屏幕分辨率自动缩放的最强代码
Aug 18 Javascript
Angular4 ElementRef的应用
Feb 26 Javascript
vue实现简单的星级评分组件源码
Nov 16 Javascript
webpack 代码分离优化快速指北
May 18 Javascript
Vue-cli项目部署到Nginx服务器的方法
Nov 01 Javascript
Bootstrap 最常用的JS插件系列总结(图片轮播、标签切换等)
Jul 14 #Javascript
基于jQuery的ajax方法封装
Jul 14 #Javascript
由浅入深剖析Angular表单验证
Jul 14 #Javascript
jQuery 3.0十大新特性最终版发布
Jul 14 #Javascript
js css+html实现简单的日历
Jul 14 #Javascript
javascript运算符——位运算符全面介绍
Jul 14 #Javascript
Angular.js 实现数字转换汉字实例代码
Jul 14 #Javascript
You might like
php str_replace的替换漏洞
2008/03/15 PHP
PHP中的cookie不用刷新就生效的方法
2012/02/04 PHP
php实现的DateDiff和DateAdd时间函数代码分享
2014/08/16 PHP
laravel 5 实现模板主题功能
2015/03/02 PHP
php简单实现快速排序的方法
2015/04/04 PHP
Yii2实现ajax上传图片插件用法
2016/04/28 PHP
Yii 2.0中场景的使用教程
2017/06/02 PHP
php微信公众号开发之二级菜单
2018/10/20 PHP
tp5(thinkPHP5)框架实现多数据库查询的方法
2019/01/10 PHP
javascript定时器完整实例
2015/02/10 Javascript
JS模仿腾讯图片站的图片翻页按钮效果完整实例
2016/06/21 Javascript
JavaScript 限制文本框不可输入英文单双引号的方法
2016/12/20 Javascript
对layui中的onevent 和event的使用详解
2019/09/06 Javascript
tensorflow: 查看 tensor详细数值方法
2018/06/13 Python
python selenium 获取标签的属性值、内容、状态方法
2018/06/22 Python
python顺序的读取文件夹下名称有序的文件方法
2018/07/11 Python
Python socket非阻塞模块应用示例
2019/09/12 Python
Python 异步协程函数原理及实例详解
2019/11/13 Python
python 求10个数的平均数实例
2019/12/16 Python
python生成13位或16位时间戳以及反向解析时间戳的实例
2020/03/03 Python
解决Jupyter notebook中.py与.ipynb文件的import问题
2020/04/21 Python
python在一个范围内取随机数的简单实例
2020/08/16 Python
Python从文件中读取数据的方法步骤
2020/11/18 Python
python和opencv构建运动检测器的实现
2021/03/03 Python
CSS3提交意见输入框样式代码
2014/10/30 HTML / CSS
canvas绘制表情包的示例代码
2018/07/09 HTML / CSS
受欢迎的大学生自我评价
2013/12/05 职场文书
教师试用期自我鉴定
2014/02/12 职场文书
《四季》教学反思
2014/04/08 职场文书
亲子活动总结
2014/04/26 职场文书
书香校园建设方案
2014/05/02 职场文书
综合素质评价自我评价
2015/03/06 职场文书
现场施工员岗位职责
2015/04/11 职场文书
检察院起诉意见书
2015/05/20 职场文书
《去年的树》教学反思
2016/02/18 职场文书
js 实现Material UI点击涟漪效果示例
2022/09/23 Javascript