2015-04-02 158 views
1

我一直在努力使用$.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调用,这是造成我的问题了。我尝试了一些没有成功的事情。任何帮助,将不胜感激。

回答

2

这是我看到的最简单的解决方案:

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.buildgridgetPlans()返回。

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函数。

+0

我在'buildHeader'函数中添加了一个'if-else',我忘了添加,并且把'lastPromise.done(...)'放在循环的外面。如果'else'从未被击中,并且'lastPromise'从未设置过,那么'lastPromise'还会解决吗?它在我的应用程序中工作,但我想知道这是否会导致一些不受欢迎的行为。 – 2015-04-02 17:51:36

+0

@RobM'lastPromise'无法解决它永远不会被设置为承诺。你需要做另外一个if-else语句来检查是否设置了lastPromise。我将通过一个示例向我的帖子添加一个编辑。 – bowheart 2015-04-02 21:35:39