2015-10-23 20 views
0

我正在遍历一个数组,并在该循环内执行一些迭代操作,可能会将某些内容添加到数组中,从而导致循环持续时间更长。 (我知道一个人不应该改变一个迭代的对象,但忍受着我。)随着集合的增长异步迭代

我使用数组作为队列的排序来首先遍历树的宽度。

这将工作得很好,除非每次迭代都是ajax调用,因此是异步的,这意味着在回调队列出列之前循环已经很久了。这意味着我的集合不会在我循环时增长,并且循环最终太短。

我的第一本能是使用闭包来捕获每次迭代的集合,但这并不会帮助收集错误地在循环后开始增长这一事实。

我的另一个想法是检查像async这样的库是否支持我想要做的事情,但是我不熟悉它并且无法在其文档中找到它。

这里是我的代码:

for (var i = 0; i < array.length; i++) { 
    if (some condition) { 
    $http.get(url).success(function (data) { 
     array.push(data); // this happens to late since this function is asynchronous 
    }); 
    } 
} 

回答

0

你应该使用延迟对象和之后所有的请求都得到了解决,将数据追加到数组

var promises = []; 
for (var i = 0; i < array.length; i++) { 
    if (some condition) { 
    promises.push($http.get(url)); 
    } 
} 

$q.all(promises).then(function(data){ 
    for (var i = 0; i < data.length; i++) { 
     array.push(data[i]); 
    } 
}); 

了解更多关于$qhere

+0

每当数组中的所有承诺都解决时,是否会运行'$ q.all'?事实之后,该阵列可能会再次增长。 – weltschmerz

0

我建议为此做出承诺:

var all = Promise.all(arr.map(function(x){ //$q.all can also work, see below 
    if(condition) { //whatever your condition is 
     //can be promises ($http.get() returns a promise) or non-promise values 
     return $http.get(); //instead of pushing it 
    } else { 
     //same as above 
     return value; //instead of pushing it 
    } 
})); 
/* all promise which represents the eventual resolution 
    of all your returned values */ 

你可以随意做任何你想要的承诺。

all.then(function(data){ 
    //data is your array with all your http responses 
}); 

约$ q.all和非承诺一个关心重视

貌似$q.all需要承诺的数组;它并没有说它会将非承诺值转换为已解决的承诺值。如果你打算使用带有非承诺值的$q.all,那么我建议你明确只是为了保证安全并将非承诺值转化为已解决的承诺。

$q.resolve(value);