jQuery通过deferred对象管理ajax异步

今天跟大家分享一个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异步的相关知识,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 在jQuery 1.5中使用deferred对象的代码(翻译)

    译者注:1. Deferred是jQuery1.5新增的一个特性,很多人把它翻译成 "异步队列",我觉得比较靠谱,毕竟和"延迟"没啥关系,不过这篇文章中我还采用deferred这个单词. 2. 这篇文章在jQuery1.5发布博客中提到,也是目前介绍deferred比较经典和深入的文章.鉴于目前中文资料比较少,特别翻译出来供大家学习参考. 3. 通篇采用意译的方式,如有不当还请大家提出. jQuery1.5中新增的Deferreds对象,可以将任务完成的处理方式与任

  • jquery基础教程之deferred对象使用方法

    一.什么是deferred对象? 开发网站的过程中,我们经常遇到某些耗时很长的javascript操作.其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的. 通常的做法是,为它们指定回调函数(callback).即事先规定,一旦它们运行结束,应该调用哪些函数. 但是,在回调函数方面,jQuery的功能非常弱.为了改变这一点,jQuery开发团队就设计了deferred对象. 简单说,deferred对象就是jQuery的回调函数

  • jQuery的deferred对象使用详解

    这个功能很重要,未来将成为jQuery的核心方法,它彻底改变了如何在jQuery中使用ajax.为了实现它,jQuery的全部ajax代码都被改写了. 但是,它比较抽象,初学者很难掌握,网上的教程也不多.所以,我把自己的学习笔记整理出来了,希望对大家有用. 本文不是初级教程,针对的读者是那些已经具备jQuery使用经验的开发者.如果你想了解jQuery的基本用法,请阅读我编写的<jQuery设计思想>和<jQuery最佳实践>. 一.什么是deferred对象? 开发网站的过程中,

  • jQuery的promise与deferred对象在异步回调中的作用

    一.前言 为了让前端们从回调的地狱中回到天堂, jQuery 也引入了 Promise 的概念. Promise 是一种令代码异步行为更加优雅的抽象,有了它,我们就可以像写同步代码一样去写异步代码. jQuery 从1.5版本开始实现了 CommonJS Promise/A 规范这一重量级方案,不过没有严格按照规范进行实现,有一些API上的差异. 好,让我们来看看他们的特性吧( 本文示例基于jquery 1.8版本以上 ). 二.示例 以前写动画时,我们通常是这么干的: $('.animateE

  • jQuery的deferred对象详解

    一.什么是deferred对象? 开发网站的过程中,我们经常遇到某些耗时很长的javascript操作.其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的. 通常的做法是,为它们指定回调函数(callback).即事先规定,一旦它们运行结束,应该调用哪些函数. 但是,在回调函数方面,jQuery的功能非常弱.为了改变这一点,jQuery开发团队就设计了deferred对象. 简单说,deferred对象就是jQuery的回调函数

  • 在jQuery1.5中使用deferred对象 着放大镜看Promise

    引言在那篇经典的关于jQuery1.5中Deferred使用方法介绍的文章中(译文见这里),有下面一段描述: $.ajax() returns an object packed with other deferred-related methods. I discussed promise(), but you'll also find then(), success(), error(), and a host of others. You don't have access to the c

  • 以jQuery中$.Deferred对象为例讲解promise对象是如何处理异步问题

    Promises是一种令代码异步行为更加优雅的抽象,它很有可能是JavaScript的下一个编程范式,一个Promise即表示任务结果,无论该任务是否完成. 在一些现代浏览器中已经提供了原生的Promise对象,其遵循Promise/A+标准.在jQuery1.5+,提供了$.Deferred(其可以被转化为promise对象).很多知名的框架中,也提供了promise对象.promise对象在javascript中已经是一种很重要的模式,它在解决异步问题时表现出的优雅,正是javascript

  • jQuery.deferred对象使用详解

    一.前言 jQuery1.5之前,如果需要多次Ajax操作,我们一般会使用下面的两种方式: 1).串行调用Ajax $.ajax({ success: function() { $.ajax({ success: function() { $.ajax({ //callbacks... }); }); }); 这种方式代码可读性差,效率低,晦涩难懂,调试和排错的复杂度大. 2).并行调用Ajax var promises = []; $.ajax({ success: function() {

  • 详解jQuery中的deferred对象的使用(一)

    deferred对象是jQuery对Promises接口的实现.它是非同步操作的通用接口,可以被看作是一个等待完成的任务,开发者通过一些通过的接口对其进行设置.事实上,它扮演代理人(proxy)的角色,将那些非同步操作包装成具有某些统一特性的对象,典型例子就是Ajax操作.网页动画.web worker等等. jQuery的所有Ajax操作函数,默认返回的就是一个deferred对象. 在jquery1.5之后的版本中,加入了一个deferred对象,也就是延迟对象,用来处理未来某一时间点发生的

  • jQuery之Deferred对象详解

    deferred对象是jQuery对Promises接口的实现.它是非同步操作的通用接口,可以被看作是一个等待完成的任务,开发者通过一些通过的接口对其进行设置.事实上,它扮演代理人(proxy)的角色,将那些非同步操作包装成具有某些统一特性的对象,典型例子就是Ajax操作.网页动画.web worker等等. jQuery的所有Ajax操作函数,默认返回的就是一个deferred对象. Promises是什么 由于JavaScript单线程的特点,如果某个操作耗时很长,其他操作就必需排队等待.为

  • jQuery中deferred对象使用方法详解

    在jquery1.5之后的版本中,加入了一个deferred对象,也就是延迟对象,用来处理未来某一时间点发生的回调函数.同时,还改写了ajax方法,现在的ajax方法返回的是一个deferred对象. 那就来看看deferred对象的用法. 1.ajax的链式回调 // ajax方法返回的是一个deferred对象,可以直接使用链式写法 $.ajax('test.json').done(function(resp){ // done 相当于success回调,其中默认的参数为success回调的

  • 利用jQuery的deferred对象实现异步按顺序加载JS文件

    前段时间看了阮一峰的jQuery的deferred对象详解一文,对jQuery中的deferred的用法了一些了解,今天看到园子里的一篇文章:关于重构JS前端框架的失败经验(顺便怀念那些死去的代码),于是把我之前写的一个利用jQuery的deferred异步按顺序加载JS文件方案分享出来,欢迎指正. 如果你现在对jQuery中的deferred还不了解,强烈建议你看一下阮一峰的jQuery的deferred对象详解一文. 加载JS文件的代码如下: 复制代码 代码如下: /* Loading Ja

随机推荐