【发布时间】:2016-07-19 23:48:42
【问题描述】:
我有一个复杂的(至少对我而言)嵌套循环、ajax 调用和延迟设置。该代码正在调用一个 API,解析出相关数据,然后使用它进一步调用其他 API。
它几乎按预期工作。我使用这个问题的答案 (Using $.Deferred() with nested ajax calls in a loop) 来构建它。这是我的代码:
function a() {
var def = $.Deferred();
var req = [];
for (var i = 0 /*...*/) {
for (var j = 0 /*...*/) {
(function(i, j) {
req.push($.ajax({
//params
}).done(function(resp) {
var def2 = $.Deferred();
var req2 = [];
for (var k = 0 /*...*/) {
for (var l = 0 /*...*/) {
req2.push(b(l));
}
}
$.when.apply($, req2).done(function() {
console.log("Got all data pieces");
def2.resolve();
})
}));
})(i, j);
}
}
$.when.apply($, req).done(function() {
console.log("Got all data");
def.resolve();
});
return def.promise();
}
function b(j) {
var def = $.Deferred();
$.when.apply(
$.ajax({
//params
})
).then(function() {
console.log("Got data piece #" + l);
def.resolve();
});
return def.promise();
}
function main() {
//...
$.when.apply($, a()).then(function() {
console.log("All done");
displayPage();
})
//...
}
这是我希望在通话完成时看到的内容
(In no specific order)
Got data piece #1
Got data piece #0
Got data piece #2
Got all data pieces
Got data piece #2
Got data piece #1
Got data piece #0
Got all data pieces
Got data piece #0
Got data piece #1
Got data piece #2
Got all data pieces
Got all data <-- These two must be last, and in this order
All done
这是我看到的
All done
Got data piece #0
Got data piece #1
Got data piece #2
Got all data pieces
Got data piece #0
Got data piece #1
Got data piece #2
Got all data pieces
Got data piece #0
Got data piece #1
Got data piece #2
Got all data pieces
我在调试器中单步执行它,函数 a() 中的“获取所有数据”行在其他所有操作完成后以正确的顺序打印,之后应该调用 def.resolve() 并解析返回的 Promise .
但是,在 main() 中,a() 被视为立即解析,代码直接跳转到打印“全部完成”并显示页面。关于为什么它不按预期等待的任何想法?
【问题讨论】:
-
你从来没有对
def2做任何事,是吗? -
你的内部
$.when.apply(...)需要在它前面有一个return是return $.when.apply(...),这样外部的promise 就会等待内部的promise。然后,您可以摆脱不必要的反模式的外部延迟。但是,整个事情确实需要重写才能更简单、更正确地使用 Promise。
标签: javascript jquery ajax jquery-deferred