自己在尝试使用jquery的promise对象的时候,出现了这个问题:
var promise1 = someAjax(); //someFunction返回jq的jqxhr对象
var promise2 = promise1.then(function (data) {
return ajax1(); //返回jq的jqxhr对象
}, function (xhr) {
return ajax2(); //返回jq的jqxhr对象
});
promise2.then(function (data) {
// 我要怎么知道
// 到底是ajax1执行成功了
// 还是ajax2执行成功了?
}, function (xhr) {
alert("error");
});
如上代码所示,promise1成功之后,我希望它执行ajax1();promise1
失败之后,我希望它执行ajax2()
。但是promise2
的话,无论是ajax1()
成功了还是ajax2()
成功了,它都会走到自己的success
的分支里对吧。
我要如何区别呢?
var promise1 = someAjax(); //someFunction返回jq的jqxhr对象
var promise2 = promise1.then(function (data) {
return ajax1(); //返回jq的jqxhr对象
return ajax2(); //返回jq的jqxhr对象
}, function (xhr) {
// nothing here
});
promise2.then(function (data) {
// ajax1执行成功,
// 和ajax2执行成功之后,
// 我如何针对它俩进行不同的操作?
}, function (xhr) {
alert("error");
});
也就是说,现在我们有两个问题。
问题一(我原本的问题):我想在执行某个ajax之后,成功的话,执行ajax1,失败的话,执行ajax2,那么如何分别对ajax1和ajax2的后续进行操作?
问题二(我追加的问题):我想在执行某个ajax之后,成功的话,执行ajax1和ajax2,那么如何分别对ajax1和ajax2的后续进行操作?
在stackoverflow上面,这个回答给了我启发,是的,使用$.when()和$.Deferred()
不废话,直接上代码。
解决问题一:
// 为每一个ajax请求声明一个变量,并设为Deferred对象
// 这一步是必须的,而且必须在$.when前面
// 因为$.when的参数得是一个Deferred对象
var someAjaxDfd = $.Deferred();
var ajax1Dfd = $.Deferred();
var ajax2Dfd = $.Deferred();
// 这是程序主体
// 首先执行someAjax
someAjax(someAjaxDfd);
$.when(someAjaxDfd).then(function (data) {//这里的参数为什么是data,因为在下面的ajax函数中,我把data当成resolve()的参数传过来了
// someAjax完成之后,如果成功,执行ajax1
ajax1(ajax1Dfd);
}, function (xhr) { //这里的参数为什么是xhr,因为在下面的ajax函数中,我把xhr当成reject()的参数传过来了
// 如果失败,执行ajax2
var data = {/* some data */};
ajax2(data, ajax2Dfd);
});
$.when(ajax1Dfd).then(function (data) {
// ajax1成功之后执行的命令
}, function (xhr) {
// ajax1失败之后执行的命令
});
$.when(ajax2Dfd).then(function (data) {
// ajax2成功之后执行的命令
}, function (xhr) {
// ajax2失败之后执行的命令
});
// 这里是三个ajax函数声明
function someAjax(dfd) {
$.ajax({
type: "GET",
url: "/someajaxurl",
contentType: "application/json",
dataType: "json",
success: function (data) {
dfd.resolve(data);
},
error: function (xhr) {
dfd.reject(xhr);
}
});
}
function ajax1(dfd) {
$.ajax({
type: "GET",
url: "/ajax1url",
contentType: "application/json",
dataType: "json",
success: function (data) {
dfd.resolve(data);
},
error: function (xhr) {
dfd.reject(xhr);
}
});
}
function ajax2(data, dfd) {
$.ajax({
type: "POST",
url: "/ajax1url",
contentType: "application/json",
dataType: "json",
data: JSON.stringify(data),
success: function (data) {
dfd.resolve(data);
},
error: function (xhr) {
dfd.reject(xhr);
}
});
}
所以我的思路的原理是,首先声明一个Deferred对象,然后把这个对象传入到ajax的函数里。如果success,那么传入的Deferred调用resolve()方法,如果error,那么传入的Deferred调用reject()方法。然后在程序中用$.when()监听这个Deferred对象,成功或失败,执行不同的指令。
所以解决问题二,和问题一大同小异:
var someAjaxDfd = $.Deferred();
var ajax1Dfd = $.Deferred();
var ajax2Dfd = $.Deferred();
// 这是程序主体
// 首先执行someAjax
someAjax(someAjaxDfd);
$.when(someAjaxDfd).then(function (data) {
// someAjax完成之后,如果成功,执行ajax1和ajax2
ajax1(ajax1Dfd);
var data = {/* some data */};
ajax2(data, ajax2Dfd);
}, function (xhr) {
// nothing here
});
$.when(ajax1Dfd).then(function (data) {
// ajax1成功之后执行的命令
}, function (xhr) {
// ajax1失败之后执行的命令
});
$.when(ajax2Dfd).then(function (data) {
// ajax2成功之后执行的命令
}, function (xhr) {
// ajax2失败之后执行的命令
});
另外,如果ajax请求返回的json格式不对,即使status为200,$.ajax()也是会走到error的eventHandler里面的,这个要注意。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。