在继续之前,我似乎无法让这些JavaScript运行完成。 ajax中的每一个都位于ajax的内部。
每次我在Chrome中加载它(并设置一个断点,我的评论说"我不希望这种情况发生在..."),它会在我的断点之前到达我的断点htmlDivs集合中有任何内容。继续之后,htmlDivs集合总是被填满,这让我相信我在尝试使用promises和.done()时做错了。
代码最好地说明了这一点:
var htmlDivs = {};
function SelectTopLevelThingFromPage(id) {
SetupHtmlDivs(id).done(
function () {
// I don't want this to happen until SetupHtmlDivs() completes
// (including all nested $.each and $.ajax)
var keys = Object.keys(htmlDivs);
// Append the htmlDivs in a specific sorted order
}
);
}
function SetupHtmlDivs(id) {
var promises = [];
$.ajax({
url: "api/GetSecondLevelThingsFromTopLevelId" + id,
method: "get",
success: function (SecondLevelThings) {
$.each(SecondLevelThings, function (i, SecondLevelThing) {
var promise = SetupHtmlForOneThing(SecondLevelThing);
promises.push(promise);
});
}
});
return $.when.apply($, promises).promise();
}
function SetupHtmlForOneThing(SecondLevelThing) {
var promises = [];
$.ajax({
url: "api/SecondLevelThing/" + SecondLevelThing.id + "/Environments",
method: "get",
success: function (Environments) {
$.each(Environments, function (k, env) {
var def = new $.Deferred();
promises.push(def);
htmlDivs[SecondLevelThing.id + "-" + env] = SecondLevelThing;
def.resolve();
});
}
});
return $.when.apply($, promises).promise();
}
答案 0 :(得分:0)
尝试以下方法:
var htmlDivs = {};
function SelectTopLevelThingFromPage(id) {
SetupHtmlDivs(id).done(
function () {
// I don't want this to happen until SetupHtmlDivs() completes
// (including all nested $.each and $.ajax)
var keys = Object.keys(htmlDivs);
// Append the htmlDivs in a specific sorted order
}
);
}
function SetupHtmlDivs(id) {
var finalPromise = new $.Deferred();
$.ajax({
url: "api/GetSecondLevelThingsFromTopLevelId" + id,
method: "get",
success: function (SecondLevelThings) {
var promises = [];
$.each(SecondLevelThings, function (i, SecondLevelThing) {
var promise = SetupHtmlForOneThing(SecondLevelThing);
promises.push(promise);
});
$.when.apply($, promises).then(function() {
finalPromise.resolve();
});
}
});
return finalPromise;
}
function SetupHtmlForOneThing(SecondLevelThing) {
var innerPromise = new $.Deferred();
$.ajax({
url: "api/SecondLevelThing/" + SecondLevelThing.id + "/Environments",
method: "get",
success: function (Environments) {
$.each(Environments, function (k, env) {
htmlDivs[SecondLevelThing.id + "-" + env] = SecondLevelThing;
});
innerPromise.resolve();
}
});
return innerPromise;
}
重大变化是:
SetupHtmlForOneThing
在ajax调用中不需要promises,因为这是success
回调中的非ajax操作。它只需要解决自己提供的单一承诺。SetupHtmlDivs
只需要一个在所有生成的内部promise都完成后得到解决的promise。