jQuery通过deferred对象管理ajax异步


Posted in Javascript onMay 20, 2016

今天跟大家分享一个jquery中的对象-deferred。其实从jQuery 1.5.0版本开始引入的一个新功能----deferred对象。不过可能在实际开发过程中用到的并不多,所以没有太在意。

什么是deferred对象?

开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的。

通常的做法是,为它们指定回调函数(callback)。即事先规定,一旦它们运行结束,应该调用哪些函数。

但是,在回调函数方面,jQuery的功能非常弱。为了改变这一点,jQuery开发团队就设计了deferred对象。

简单说,deferred对象就是jQuery的回调函数解决方案。在英语中,defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行。

这里先不说deferred的概念,我们先看一个例子。

还记得初学的时候,遇到一个实例,先是要ajax请求一个接口(a.json),从返回的数据中获得一个id1值。然后再请求一个接口(b.json)获得id2,最后需要对这两个id值同时进行操作。

错误解法

那个时候初学,首先想到的方案(现在想想,很傻很天真...)

var id1, id2;
$.ajax({
url: 'a.js',
dataType: 'json',
type: 'get',
success: function(d){
id1 = d.item.id;
}
});
$.ajax({
url: 'b.js',
dataType: 'json',
type: 'get',
success: function(d){
id2 = d.item.id;
}
})
alert('id1='+id1+','+ 'id2='+ id2);

因为那个时候,还没有理解异步的概念,所以以为,第二次ajax的时候id已经有值了,但是运行之后才发现,变量id其实根本没被赋值。想要测试上面代码,点这里

也就是这一刻,我真正明白了:ajax是异步的!!!。

傻瓜式解法

发现上面那个方法不能用之后,分析了一下,弹出undefined是因为弹出之前id还没有被赋值,那我保证在弹出之前给id赋值不就解决了吗?好的,于是我想到了下面这个方法:

var id1; 
$.ajax({
url: '/test/json/a.js',
dataType: 'json',
type: 'get',
success: function(d){
id1 = d.item.id;
$.ajax({
url: '/test/json/b.js',
dataType: 'json',
type: 'get',
success: function(f){
id2 = f.item.id;
alert('id1='+id1+','+ 'id2='+ id2);
}
});
}
})

逻辑虽然正确了,但总觉得怪怪的,如果这里需要嵌套3层呢?4层呢?。。。ajax里面嵌套ajax,如果数据很多,访问速度慢,嵌套更多层,会导致性能下降、影响用户体验、代码不好维护等等问题。所以一般不推荐这种方法。总之,这种写法让我难以接受。

所以思来想去,觉得不妥。。。然后那个时候就在一个前端群里,询问各种大牛,直到一个大牛告诉我让我百度一下deferred,后来认真学习了下,觉得不错。

使用deferred对象

deferred对象简介

deferred是jquery中的扩展的一个对象(1.5.0以上的版本支持deferred)。defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行。

简单说,deferred对象就是jQuery的回调函数解决方案。

再简单说,deferred对象用来管理异步操作,而ajax就是一种异步操作。

deferred基本语法

deferred让ajax支持新的写法,代码如下:

$.ajax({
url: '/test/json/a.js',
dataType: 'json',
type: 'get'
})
.done(function() {
alert("成功啦!");
})
.fail(function() {
alert("失败了...");
})

这个大家应该都知道。现在在编辑器敲入ajax,然后回车,提示的ajax语法结构就是这样链式的写法。

done函数就是ajax请求成功的回到函数;

fail函数就是ajax请求失败的回调函数。

使用deferred的解决方法

var ajax1 = $.ajax({
url: '/test/json/a.js',
dataType: 'json',
type: 'get'
});
var ajax2 = $.ajax({
url: '/test/json/b.js',
dataType: 'json',
type: 'get',
});
$.when(ajax1,ajax2).done(function(d1,d2){
var id1 = d1[0].item.id;
var id2 = d2[0].item.id;
alert('id1='+id1+', '+ 'id2='+ id2);
}).fail(function(){
alert('error');
});

值得一提的是,上面代码中done函数的参数,对应的是前面每一个ajax请求返回的数据

上面的代码中,用到了deferred对象的when方法。

它的描述是:

提供一种方法来执行一个或多个对象的回调函数。

这里的ajax1和ajax2就是deferred对象,done和fail就是回调函数。上面代码的意思是:

只有当两个ajax请求都成功返回数据时,执行done函数;只要有一个请求不成功,就执行fail函数。

另外值得一提的是:$.when方法的参数,只支持deferred对象,而ajax返回的就是deferred对象。`

这就已经实现了上面的需求了。请求两个接口,获得两个数据,都成功时,对这两个数据同时进行处理。而且这种链式写法,让读者一目了然,而且便于维护扩展。

deferred方法汇总

提到的方法

$.Deferred():生成一个deferred对象。

$.when() 为多个操作指定回调函数。

deferred.done():指定操作成功后的回调函数

deferred.fail():指定操作失败后的回调函数

未提到的方法

•deferred.resolve()方法和deferred.reject()方法

deferred对象执行回调函数之前会有一个执行状态的存在,执行状态一共有三种———未完成、已完成和已失败。

未完成状态,则会继续等待,或者执行progress()指定的回调函数。

已完成状态,则会执行done()方法指定的回调函数。

已失败状态,则会执行fail()方法指定的回调函数。

所以这里的deferred.resolve()方法就是手动将deferred对象的状态改为已完成,继而执行done方法; deferred.reject()方法就是手动将状态改为已失败,继而执行fail方法。

下面来看一个例子:

var defer = $.Deferred(); // 新建一个Deferred对象

var wait = function(defer){


var tasks = function(){
defer.resolve(); // 改变Deferred对象为已完成状态


 alert("执行完毕!");


};


setTimeout(tasks,5000);


return defer;

};
  $.when(wait(defer))

.done(function(){

 alert("succeed"); 

 })

.fail(function(){

 alert("failed"); 

});

结果:等待5秒钟,先弹出“succeed”,在弹出“执行完毕!”。

分析一下代码执行过程:

$.when()里面的参数是wait函数,也就是一个deferred对象,所以可以继续执行setTimeout函数,等待5s,执行tasks函数,然后手动改变了状态为“已完成”,所以执行done方法,弹出“succeed”,然后弹出“执行完毕!”。

deferred.then():有时为了省事,可以把done()和fail()合在一起写,这就是then()方法。

function successFun(){
alert("yes");
}
function failFun(){
alert('fail');
}
$.when($.ajax({
url: '/test/json/a.js',
dataType:'json',
type: 'get'
}))
.then(successFun, failFun);

当then方法只有一个参数时,相当于done方法。当有两个参数时,第一个相当于done方法,第二个相当于fail方法。

总结

deferred对象通过对一个ajax请求的各种回调函数的控制,让jquery写ajax变的简单、容易维护、容易扩展。

以上所述是小编给大家介绍的jQuery通过deferred对象管理ajax异步的相关知识,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
浏览器加载、渲染和解析过程黑箱简析
Nov 29 Javascript
利用javascript判断文件是否存在
Dec 31 Javascript
jQuery基础知识小结
Dec 22 Javascript
使用mini-define实现前端代码的模块化管理
Dec 25 Javascript
js实现格式化金额,字符,时间的方法
Feb 26 Javascript
jQuery实现网站添加高亮突出显示效果的方法
Jun 26 Javascript
JS选中checkbox后获取table内一行TD所有数据的方法
Jul 01 Javascript
jquery仅用6行代码实现滑动门效果
Sep 07 Javascript
深入浅析react native es6语法
Dec 09 Javascript
javascript中数组和字符串的方法对比
Jul 20 Javascript
scroll事件实现监控滚动条并分页显示(zepto.js)
Dec 18 Javascript
如何基于javascript实现贪吃蛇游戏
Feb 09 Javascript
Bootstrap3学习笔记(三)之表格
May 20 #Javascript
快速获取/设置iframe内对象元素的几种js实现方法
May 20 #Javascript
Bootstrap3学习笔记(二)之排版
May 20 #Javascript
js获取iframe中的window对象的实现方法
May 20 #Javascript
BootStrap3学习笔记(一)之网格系统
May 20 #Javascript
有关JavaScript中call()和apply() 的一些理解
May 20 #Javascript
Bootstrap表格和栅格分页实例详解
May 20 #Javascript
You might like
PHP连接SQLServer2005的实现方法(附ntwdblib.dll下载)
2012/07/02 PHP
PHP遍历XML文档所有节点的方法
2015/03/12 PHP
php去除字符串中空字符的常用方法小结
2015/03/17 PHP
PHP上传文件参考配置大文件上传
2015/12/16 PHP
PHP 5.6.11 访问SQL Server2008R2的几种情况详解
2016/08/08 PHP
详解no input file specified 三种解决方法
2019/11/29 PHP
URI、URL和URN之间的区别与联系
2006/12/20 Javascript
JQuery 动画卷页 返回顶部 动画特效(兼容Chrome)
2010/02/15 Javascript
javascript 45种缓动效果 非常酷
2011/06/28 Javascript
借助javascript代码判断网页是静态还是伪静态
2014/05/05 Javascript
node.js中的fs.chown方法使用说明
2014/12/16 Javascript
jquery实现textarea 高度自适应
2015/03/11 Javascript
JavaScript实现的圆形浮动标签云效果实例
2015/08/06 Javascript
Bootstrap table两种分页示例
2016/12/23 Javascript
简单谈谈vue的过渡动画(推荐)
2017/10/11 Javascript
实现div内部滚动条滚动到底部和顶部的代码
2017/11/15 Javascript
vue自定义一个v-model的实现代码
2018/06/21 Javascript
微信小程序实现的动态设置导航栏标题功能示例
2019/01/31 Javascript
vue实现随机验证码功能的实例代码
2019/04/30 Javascript
vue配置文件实现代理v2版本的方法
2019/06/21 Javascript
[02:17]《辉夜杯》TRG战队巡礼
2015/10/26 DOTA
wxPython 入门教程
2008/10/07 Python
从零学python系列之数据处理编程实例(二)
2014/05/22 Python
Python数据结构与算法之列表(链表,linked list)简单实现
2017/10/30 Python
python PyTorch参数初始化和Finetune
2018/02/11 Python
关于Python字符串显示u...的解决方式
2020/03/06 Python
PyQt5中QSpinBox计数器的实现
2021/01/18 Python
科尔士百货公司官网:Kohl’s
2016/07/11 全球购物
GOLFINO英国官网:高尔夫服装
2020/04/11 全球购物
出国留学担保书
2014/05/20 职场文书
个人职业及收入证明
2014/10/13 职场文书
教师廉洁自律个人总结
2015/02/10 职场文书
2016七一建党节慰问信
2015/11/30 职场文书
青年岗位能手事迹材料(2016推荐版)
2016/03/01 职场文书
Java基于Dijkstra算法实现校园导游程序
2022/03/17 Java/Android
Golang 字符串的常见操作
2022/04/19 Golang