我有一堆嵌套函数从ajax调用返回延迟对象。这是我的代码看起来像
function makeCalls() {
var ajaxDfd1 = $.ajax(...);
ajaxDfd1.then(function() {
// want to execute after first call
var ajaxDfd2 = $.ajax(...);
ajaxDfd2.done(function() {
// want to execute after second call
});
return ajaxDfd2;
});
return ajaxDfd1;
}
makeCalls().done(function() {
// stuff here was executed early
});
但我的电话没有按照我打算成为他们的顺序执行。似乎在makeCalls().done()
实际完成之前调用ajaxDfd2
内的东西。
答案 0 :(得分:2)
Choc,
你在答案中做出了错误的假设;即$.ajax()
返回“常规对象”。
这不正确。
$.ajax()
返回一个jqXHR对象,它是Promise的超集,即。它具有Promise的所有方法以及其他特定于AJAX的方法(例如.abort()
)。
如果$.ajax()
返回的对象不是Promise兼容的,那么问题中的代码会在尝试执行makeCalls().done(...)
时出错。
首先执行.done()
函数的原因是函数返回外部 jqXHR。
以下是实现您期望的行为的几种方法:
function makeCalls() {
var dfrd = new Deferred();
$.ajax(...).then(function() {
$.ajax(...).done(dfrd.resolve);
});
return dfrd.promise();
}
makeCalls().done(function(data) {
// ...
});
或
function makeCalls(fn) {
$.ajax(...).then(function() {
$.ajax(...).done(fn);
});
}
makeCalls(function(data) {
// ...
});
你甚至可以尝试:
function makeCalls() {
return $.ajax(...).then(function() {
return $.ajax(...);
});
}
makeCalls().done(function() {
// ...
});
答案 1 :(得分:0)
我知道我一定是弄错了,花了很长时间盯着这个: When should I use jQuery deferred's "then" method and when should I use the "pipe" method?
后来我意识到我做不到
var dfdObj = $.ajax(...);
dfdObj.then(...);
return dfdObj;
这实际上并不返回延迟对象。它返回一个Ajax对象,由于它是一个常规对象,它会自动归类为已解析,因此.done()
函数被提前调用。相反,如果我想返回var
var dfdObj = $.ajax(...).then(...);
return dfdObj;
答案 2 :(得分:0)
您的代码的工作方式如下:
function makeCalls() {
var ajax1 = $.ajax(…);
var ajax1and2 = ajax1.then(makeCall2);
function makeCall2() {
// want to execute after first call
var ajax2 = $.ajax(…);
ajax2.done(after2);
function after2() {
// want to execute after second call
});
return ajax2;
});
return ajax1;
}
var ajax1 = makeCalls();
ajax1.done(function() {
// stuff here was executed early
});
ajax1and2
是您想要的then
/ pipe
电话的结果。对它的回调将等待等待makeCall2
的{{1}}(即ajax2
)的结果。它等于ajax1
回调。
然而,您的after2
函数会返回makeCalls
对象(您可以看到我将其分配给全局ajax1
变量)以及ajax1
和已完成-callback将在你的第一个ajax完成后执行。
因此,您需要返回makeCall2
延迟:
ajax1and2