使用JQuery Deferred对象的then() 解决多个AJAX操作顺序依赖的问题
原文地址:http://www.2cto.com/kf/201507/424202.html
之前的文章javascript异步代码的回调地狱中提到了编写AJAX代码经常遇到的3个问题,现在我们看下如何利用then()解决第2个问题:如果AJAX请求之间存在依赖关系,我们的代码就会形成Pyramid of Doom(金字塔厄运)。比如我们要完成这样一件事:有4个供Ajax访问的url地址,需要先Ajax访问第1个,在第1个访问完成后,用拿到的返回数据作为参数再访问第2个,第2个访问完成后再第3个...以此到4个全部访问完成。按照这样的写法,似乎会变成这样:
$.ajax({
url: url1,
success: function(data){
$.ajax({
url: url2,
data: data,
success: function(data){
$.ajax({
//...
});
}
});
}
});
1.Deferred.then()相当于Deferred.done()、Deferred.fail()、Deferred.progress()的合体,可以同时注册3个状态下的回调函数。
function success(data)
{
alert(success data = + data);
} function fail(data)
{
alert(fail data = + data);
} function progress(data)
{
alert(progress data = + data);
} var deferred = $.Deferred(); // 一起注册回调
deferred.then(success, fail, progress); // 分别注册回调
deferred.done(success);
deferred.fail(fail);
deferred.progress(progress); deferred.notify(%);
deferred.resolve(ok);
当然我们也可以像done()一样,多次调用then()注册回调函数。then()虽然可以这么使用,但是实际开发中一般不这么用,因为没有啥必要。JQuery1.8之前,这就是then()方法的作用。
2.Deferred.then()解决多个异步操作之间有依赖的问题,这才是then()真正有意义的场景。JQuery1.8之后,then()取代了过时的pipe()方法。这种场景下,我们需要使用Deferred.then()返回的新Promise对象。上面的第一种使用方式,我们忽略了Deferred.then()的返回值。
var deferred = $.Deferred(); // 使用then()注册一个resolved状态的回调函数,并返回一个过滤后的promise
// 返回的filtered已经不是原来的Deferred或者Promise对象了
var filtered = deferred.then(function( value ) {
alert(trigger Deferred filter.value=+value);//
return value * ;
}); // 用过滤后的Promise再次注册回调函数
filtered.done(function( value ) {
alert(filtered value= + value);//
}); deferred.resolve( );
我们用deferred.then()注册了一个完成状态下的回调函数,这个回调函数得到的值是5;之后用filtered这个新的Promise注册回调函数,这个回调函数中得到的值是10(第一个回调函数的返回结果)。现在我们看下JQuery官方对then的解释:
These filter functions can return a new value to be passed along to the promise's .done() or .fail() callbacks, or they can return another observable object (Deferred, Promise, etc) which will pass its resolved / rejected status and values to the promise's callbacks. If the filter function used is null, or not specified, the promise will be resolved or rejected with the same values as the original.
我们知道deferred.resolve()、deferred.reject()、deferred.notify()可以指定参数值,这个参数会传递给相应状态下的回调函数。如果我们使用的是done()、fail()、progress()注册的回调函数,那么某个状态下的所有回调函数得到的都是相同参数。但是如果我们使用了then()注册回调函数,那么第一回调函数的返回值将作为第二个回调函数的参数,同样的第二个函数的返回值是第三个回调函数的参数。可以对比下面的2段代码,体会下done()和then的差别。
var deferred = $.Deferred(); // done()返回的仍然是原来的Deferred对象
var done_ret = deferred.done(function(data){
alert(data=+data);//
return * data;
});
alert(deferred == done_ret);//true done_ret.done(function(data){
alert(data=+data);//
}); deferred.resolve( );
var deferred = $.Deferred(); // then()返回的是一个新Promise对象
//then注册的回调函数的返回值将作为这个新Promise的参数
var then_ret = deferred.then(function(data){
alert(data=+data);//
return * data;
});
alert(then_ret == deferred);//false then_ret.done(function(data){
alert(data=+data);//
}); deferred.resolve( );
同样地,Deferred.then也能够实现rejected和pending状态的回调函数过滤
var defer = $.Deferred();
var filtered = defer.then( null, function( value ) {
return value * ;
}); defer.reject( ); filtered.fail(function( value ) {
alert( Value is ( * = ) : + value );
});
下面这段代码可以实现chain tasks,解决异步操作中回调难的问题。
var defered = $.Deferred();
var promise1 = defered.then(function(data){
alert(data);//
return data+=;
});
var promise2 = promise1.then(function(data){
alert(data);//
return data+=;
});
var promise3 = promise2.then(function(data){
alert(data);//
return data+=;
});
promise3.done(function(data){
alert(data);//
});
defered.resolve();
正是由于then()这个特性,我们就可以上面复杂的AJAX嵌套改成如下形式:
var promise1 = $.ajax(url1);
var promise2 = promise1.then(function(data){
return $.ajax(url2, { data: data });
});
var promise3 = promise2.then(function(data){
return $.ajax(url3, { data: data });
});
promise3.done(function(data){
// data retrieved from url3
});
使用JQuery Deferred对象的then() 解决多个AJAX操作顺序依赖的问题的更多相关文章
- javascript --- jQuery --- Deferred对象
javascript --- jQuery --- Deferred对象 javascript的函数式编程是多么引人入胜,jQuery使代码尽可能的精简,intelligent! defer - 必应 ...
- jQuery.Deferred对象
一.前言 jQuery1.5之前,如果需要多次Ajax操作,我们一般会使用下面的两种方式: 1).串行调用Ajax $.ajax({ success: function() { $.ajax({ su ...
- JQuery Deferred 对象
http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html <jQu ...
- javascript异步代码的回调地狱以及JQuery.deferred提供的promise解决方式
我们先来看一下编写AJAX编码常常遇到的几个问题: 1.因为AJAX是异步的,全部依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套.ajax等异步操作越多,嵌套层次就会越 ...
- jQuery Deferred对象详细源码分析(-)
本系列文章讲介绍这个Deferred东西到底拿来干什么,从1.5版本加进来,jQuery的很多代码都重写了.直接先上源码分析了,清楚了源码分析,下节将讲具体的应用 以及应用场景. 创建对象 var d ...
- JQuery Deferred 对象剖析
JQuery 中利用 Deferred 对象提供类似 ES2016(aka. es7) 中 Promise 的功能. JQuery 中的 AJAX 请求函数返回的就是 Deferred 对象. 通过使 ...
- JQuery Deferred对象使用小结
场景描述 如下,打开页面时,获取默认选中的项目,同时也会初始化Combobox下拉框下拉列表数据 问题描述 获取默认选中项目及下拉列表的js函数位于common.js文件,类似如下: // 根据项目类 ...
- 使用 jQuery Deferred 和 Promise 创建响应式应用程序
这篇文章,我们一起探索一下 JavaScript 中的 Deferred 和 Promise 的概念,它们是 JavaScript 工具包(如Dojo和MochiKit)中非常重要的一个功能,最近也首 ...
- jQuery Deferred和Promise的使用介绍:
deferred对象是从jquery1.5.0引入的一个新对象,ES6也引入了Promise的正式规范. 抽象来说,deferreds 可以理解为表示需要长时间才能完成的耗时操作的一种方式,相比于阻塞 ...
随机推荐
- 企业和开发人员究竟该如何适应web标准?
以下几点注意事项仅供参考:完善的前期策划和分析完善的前期逻辑模型以及项目规范性文档的制定尽可能将行政性干预移到策划阶段(按照国内的情况,做到这一点可能很困难)尽可能向后兼容,在项目规范性文档制定阶段对 ...
- 对象转化为 xml字符串
public static string ToXml<T>(this T o) where T : new() { string retVal; using (var ms = new M ...
- 为什么@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
Spring Boot会自动根据jar包的依赖来自动配置项目,例如当你项目下面有HSQLDB的依赖,Spring Boot会自动创建默认的内存数据库的数据源DataSource, 但我们使用Mybat ...
- powershell 设置环境变量 -- go 单元测试 exit status 3221225781
执行单元测试时出错 go test -run TestImage 错误提示如下: exit status 3221225781 这个错误的意思是需要加载对应的库文件找不到,加载对应的库文件就习. 但是 ...
- Java学习第三周摘要
20145307<Java程序设计>第三周学习总结 教材学习内容总结 认识对象 类类型 Java可区分为基本类型和类类型两大类型系统,其中类类型也称为参考类型.sun就是一个类类型变量,类 ...
- 20145324 《Java程序设计》第3周学习总结
20145324 <Java程序设计>第3周学习总结 教材学习内容总结 第四章 1.要产生对象必须先定义类,类是对象的设计图,对象是类的实例,建立实例要用new 2.参数名称与对象数据成员 ...
- 20145331 《Java程序设计》第4周学习总结
20145331 <Java程序设计>第4周学习总结 教材学习内容总结 •第六章 1.继承的定义与特点: 子类继承父类的特征和行为,使得子类具有父类的各种属性和方法.或子类从父类继承方法, ...
- Python学习札记(二) python3.5安装 + (假装是)第一个Python程序
参考: Mac OS 安装 Python3.5 廖雪峰Python教程:安装Python 笔记: 安装: 1.官方网站下载安装包:安装程序 2.执行安装程序完成Python3.5包的安装. 3.安装P ...
- C++中的指针和数组
最近看C++编程思想,看到第十三章动态内存管理的时候把自己给绕进去了,主要是在数据和指针这块弄混了.现在把找到的一些资料总结如下: 1. 数组是数组,指针是指针,两者并不等价: 2.数组在作为左值的时 ...
- 如何将JS里变量的值赋给文本框
举个栗子: <html><HEAD><script type="text/javascript" language="Javascript1 ...