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 相关文章推荐
js实现的跟随鼠标移动的时钟效果(中英文日期显示)
Jan 17 Javascript
js输出阴历、阳历、年份、月份、周示例代码
Jan 29 Javascript
jQuery实现带有动画效果的回到顶部和底部代码
Nov 04 Javascript
利用jQuery插件imgAreaSelect实现图片上传裁剪(同步显示图像位置信息)
Dec 02 Javascript
bootstrap datetimepicker日期插件超详细使用方法介绍
Feb 23 Javascript
jquery将标签元素的高设为屏幕的百分比
Apr 19 jQuery
jQuery Form插件使用详解_动力节点Java学院整理
Jul 17 jQuery
解决vuejs项目里css引用背景图片不能显示的问题
Sep 13 Javascript
如何在微信小程序里面退出小程序的方法
Apr 28 Javascript
微信网页登录逻辑与实现方法
Apr 29 Javascript
五分钟搞懂Vuex实用知识(小结)
Aug 12 Javascript
Vue h函数的使用详解
Feb 18 Vue.js
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数学运算
2011/12/30 PHP
深入file_get_contents函数抓取内容失败的原因分析
2013/06/25 PHP
php数组查找函数总结
2014/11/18 PHP
php数组添加元素方法小结
2014/12/20 PHP
CI框架的安全性分析
2016/05/18 PHP
PHP析构函数destruct与垃圾回收机制的讲解
2019/03/22 PHP
js验证表单第二部分
2006/11/25 Javascript
使用JQUERY进行后台页面布局控制DIV实现左右式
2014/01/07 Javascript
jQuery 设置 CSS 属性示例介绍
2014/01/16 Javascript
简单实现的JQuery文本框水印插件
2016/06/14 Javascript
通过javascript进行UTF-8编码的实现方法
2016/06/27 Javascript
Three.js学习之正交投影照相机
2016/08/01 Javascript
微信小程序 wx.request(OBJECT)发起请求详解
2016/10/13 Javascript
Javascrip实现文字跳动特效
2016/11/27 Javascript
Vue的MVVM实现方法
2017/08/16 Javascript
如何使用 vue + d3 画一棵树
2018/12/03 Javascript
微信小程序使用map组件实现获取定位城市天气或者指定城市天气数据功能
2019/01/22 Javascript
elementUI 动态生成几行几列的方法示例
2019/07/11 Javascript
layui使用templet格式化表格数据的方法
2019/09/16 Javascript
Python实现接受任意个数参数的函数方法
2018/04/21 Python
Python基础学习之类与实例基本用法与注意事项详解
2019/06/17 Python
Python使用LDAP做用户认证的方法
2019/06/20 Python
Python3打包exe代码2种方法实例解析
2020/02/17 Python
django orm模块中的 is_delete用法
2020/05/20 Python
python实现三壶谜题的示例详解
2020/11/02 Python
浅谈Python xlwings 读取Excel文件的正确姿势
2021/02/26 Python
英国快时尚女装购物网站:PrettyLittleThing
2018/08/15 全球购物
英国文具、办公用品和科技商店:Ryman
2018/09/27 全球购物
社区庆八一活动方案
2014/02/02 职场文书
校园安全教育广播稿
2014/02/17 职场文书
国旗下的演讲稿
2014/05/08 职场文书
干部对照检查材料范文
2014/08/26 职场文书
本科毕业论文指导教师评语
2014/12/30 职场文书
2015年财务工作总结范文
2015/03/31 职场文书
Django程序的优化技巧
2021/04/29 Python
JavaScript中10个Reduce常用场景技巧
2022/06/21 Javascript