在循环jquery中等待ajax返回
问题描述:
我一直在努力使用$.Deferred
对象来使其工作。这是存根设置。在循环jquery中等待ajax返回
g_plans = [];
$(function(){
// I have to use a custom ajax function, but it returns a promise obj
var pageLoadPromise.ajax{(
url: //call to webmethod
});
pageLoadPromise.done(matrix.buildGrid);
...
});
(function(matrix,$,undefined){
var matrix.buildGrid = function(components){
var gridData = data.d.components;
buildHeader(gridData);
buildRows(gridData);
};
function buildHeader(components){
$.each(components,function(key,component){
//does some stuff
if(this === that){
//do some other stuff
}
else{
getPlans(copmonent.COMPONENT_ID);
//does other stuff
}
});
}
}
function buildRows(components){
//does stuff, but uses data from getPlans
}
function getPlans(component){
var planPromise = ajax({
url: //call to webmethod
data:{ componentId:component}
planPromise.done(function(data){
g_plans.push({componentId:componentId,plans:data.d.plans});
});
}
})(window.matrix = window.matrix || {}, jQuery);
问题是buildRows
开始了getPlans
有时间来完成它的Ajax调用,这是造成我的问题了。我尝试了一些没有成功的事情。任何帮助,将不胜感激。
答
这是我看到的最简单的解决方案:
1)有getPlans()
返回planPromise
承诺,然后可以处理回到buildHeader()
功能。
function getPlans(component) {
var planPromise = ajax({
url: //call to webmethod
data:{ componentId:component}
});
planPromise.done(function(data) {
g_plans.push({componentId: data.componentId, plans: data.d.plans});
});
return planPromise; // return the promise!
}
2)使用承诺调用从buildHeader()
功能buildRows()
而不是matrix.buildgrid
从getPlans()
返回。
function buildHeader(components) {
var lastPromise;
$.each(components, function (key, component) {
lastPromise = getPlans(component.COMPONENT_ID);
});
lastPromise.done(function() {
buildRows(components);
});
}
这里是一个JSFiddle说明的基本思想。
第二步是不必要的,我发现它更容易。另一种选择是从buildHeader()
返回lastPromise
,并在matrix.buildgrid
处理它。
var matrix.buildgrid = function(components) {
var gridData = components;
var lastPromise = buildHeader(gridData);
lastPromise.done(function() {
buildRows(components);
});
};
function buildHeader(components) {
var lastPromise;
$.each(components, function (key, component) {
lastPromise = getPlans(component.COMPONENT_ID);
});
return lastPromise;
}
编辑:
要处理的lastPromise
从未得到设置为一个承诺的情况下,你必须做这样的事情:
if (lastPromise && typeof lastPromise === 'object') {
lastPromise.done(function() {
buildRows(components);
});
} else {
buildRows(components); // or whatever needs to happen here.
}
这里有一个JSFiddle包括在该位buildHeader
函数。
我在'buildHeader'函数中添加了一个'if-else',我忘了添加,并且把'lastPromise.done(...)'放在循环的外面。如果'else'从未被击中,并且'lastPromise'从未设置过,那么'lastPromise'还会解决吗?它在我的应用程序中工作,但我想知道这是否会导致一些不受欢迎的行为。 – 2015-04-02 17:51:36
@RobM'lastPromise'无法解决它永远不会被设置为承诺。你需要做另外一个if-else语句来检查是否设置了lastPromise。我将通过一个示例向我的帖子添加一个编辑。 – bowheart 2015-04-02 21:35:39