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实现手风琴效果实例代码
Nov 15 Javascript
使用js显示当前时间示例
Mar 02 Javascript
iframe如何动态创建及释放其所占内存
Sep 03 Javascript
node.js中的querystring.unescape方法使用说明
Dec 10 Javascript
jQuery实现的感应鼠标悬停图片色彩渐显效果
Mar 03 Javascript
angularjs 源码解析之scope
Aug 22 Javascript
webpack构建react多页面应用详解
Sep 15 Javascript
JS实现的简单四则运算计算器功能示例
Sep 27 Javascript
Vue组件库发布到npm详解
Feb 17 Javascript
使用jquery模拟a标签的click事件无法实现跳转的解决
Dec 04 jQuery
[原创]微信小程序获取网络类型的方法示例
Mar 01 Javascript
jQuery 选择方法及$(this)用法实例分析
May 19 jQuery
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 IP及IP段进行访问限制的代码
2008/12/17 PHP
PHP字符编码问题之GB2312 VS UTF-8解决方法
2011/06/23 PHP
PHP仿博客园 个人博客(2) 数据库增添改删
2013/07/05 PHP
php实现批量压缩图片文件大小的脚本
2014/07/04 PHP
Yii使用find findAll查找出指定字段的实现方法
2014/09/05 PHP
ThinkPHP处理Ajax返回的方法
2014/11/22 PHP
CI框架(ajax分页,全选,反选,不选,批量删除)完整代码详解
2016/11/01 PHP
用js查找法实现当前栏目的高亮显示的代码
2007/11/24 Javascript
JavaScript学习笔记之获取当前目录的实现代码
2010/12/14 Javascript
js中浮点型运算BUG的解决方法说明
2014/01/06 Javascript
用js通过url传参把数据从一个页面传到另一个页面
2014/09/01 Javascript
jQuery实现弹出窗口中切换登录与注册表单
2015/06/05 Javascript
JavaScript如何禁止Backspace键
2015/12/02 Javascript
javascript中闭包(Closure)详解
2016/01/06 Javascript
微信小程序实现刷脸登录
2018/05/25 Javascript
微信小程序WebSocket实现聊天对话功能
2018/07/06 Javascript
VUE渲染后端返回含有script标签的html字符串示例
2019/10/28 Javascript
聊聊Vue中provide/inject的应用详解
2019/11/10 Javascript
解决Vue-cli无法编译es6的问题
2020/10/30 Javascript
[02:02:38]VG vs Mineski Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
[50:54]完美世界DOTA2联赛 GXR vs IO 第三场 11.07
2020/11/10 DOTA
python中遍历文件的3个方法
2014/09/02 Python
Python中的迭代器与生成器高级用法解析
2016/06/28 Python
python多进程实现文件下载传输功能
2018/07/28 Python
PySide和PyQt加载ui文件的两种方法
2019/02/27 Python
pyqt实现.ui文件批量转换为对应.py文件脚本
2019/06/19 Python
matplotlib 曲线图 和 折线图 plt.plot()实例
2020/04/17 Python
Python爬虫与反爬虫大战
2020/07/30 Python
HTML5 video 视频标签使用介绍
2014/02/03 HTML / CSS
英国领先的票务代理商之一:The Ticket Factory
2019/02/09 全球购物
什么是组件架构
2016/05/15 面试题
士力架广告词
2014/03/20 职场文书
没有孩子的离婚协议书怎么写
2014/09/17 职场文书
2015关爱留守儿童工作总结
2014/12/12 职场文书
2015年机关纠风工作总结
2015/05/15 职场文书
2016年学校“3.12”植树节活动总结
2016/03/16 职场文书