我有一个使用jQuery 1.11.1的页面,并且已经使用了Deferred和Promises。
该页面执行大约13个单独的ajax调用,然后将一系列单选按钮填充到表中。因为ajax调用不一定按表中定义的顺序完成,所以我实现了以下内容。这有效:
function getSubscriptionTypes(st_id) {
var d = $.Deferred();
if(st_id){
$.ajax({
type: "POST",
url: "addUser.php",
data: { st_id: st_id },
dataType: "json"
}).done(function(p) {
d.resolve(p);
}).fail(d.reject);
return d.promise();
}
}
function loadSubscriptionTypes() {
$('.subsList').each(function() {
var st_id = $(this).closest("tr").data('stId');
var st_id = String(st_id);
var sub_types = getSubscriptionTypes(st_id).done(function(c){
$.each(c, function(k,v) {
$('#stid-'+st_id).append('<input type="radio" value="' + v.ut_id + '-' + st_id + '" data-st-id="' + st_id + '" name="stid[' + st_id + ']"> ' + v.type + ' ');
});
});
});
}
loadSubscriptionTypes();
我现在正在努力做以下事情 - 在所有单选按钮都附加到我的表后,我想使用jQuery来定位它们(预先选择某些按钮)。我不确定如何做到这一点,但想象一下使用另一个 Deferred / Promise?
所以我尝试将代码修改为:
function loadSubscriptionTypes() {
var deferredObject = $.Deferred();
// Existing code above
deferredObject.resolve();
return deferredObject.promise();
}
var promise = loadSubscriptionTypes();
promise.done(function () {
console.log("loadSubscriptionTypes() done");
});
当加载页面时,在所有ajax调用完成之前,我的控制台中会出现文本“loadSubscriptionTypes()done”。
基本上,在执行其他任务之前,我不知道如何告诉它等待loadSubscriptionTypes()
中的所有工作完成。
请有人提出建议或指出我正确的方向吗?
PS - 我知道可能有更好的方法来编写我的代码,但是这已经使用我迄今为止能够找到/学习的内容,以及将正确的单选按钮加载到桌子,实际上是有效的。
答案 0 :(得分:1)
首先,确保getSubscriptionTypes
实际返回Promise。没有必要在其中创建自己的$.Deferred
- 这样做是 promise antipattern :
function getSubscriptionTypes(st_id) {
return $.ajax({
type: "POST",
url: "addUser.php",
data: { st_id: st_id },
dataType: "json"
});
}
然后,在你的loadSubscriptionTypes
函数中,将所有返回的promises累积到一个数组中:
var promise = getSubscriptionTypes(st_id);
push(myArray, promise);
promise.done(function(c) {
$.each(c, function(k,v) {
...
});
});
在外部循环之后,使用$.when
等待所有这些承诺得到解决:
$.when.apply($, myArray).then( ... );