AngularJS在每个循环中依次链承诺 [英] AngularJS Sequentially Chain Promises in forEach Loops
问题描述
我有vm.planWeek.dinner循环遍历每行,然后附加'menuType'和'trackMenuIds'数组,然后在MongoDB调用中使用搜索条件。这一切工作正常,但关键的因素,是每个工厂调用返回,我将返回的项目的ID添加到trackMenuIds数组。原因是它构建了一个已经返回的数组,所以他们可以在下次调用中忽略,即通过$ nin。
vm.reviewWeek = function(){
//在每个迭代中更新数组并在工厂调用中使用
var trackMenuIds = [];
angular.forEach(vm.planWeek.dinner,function(day){
//添加两个项目到当天(当前行)传递到工厂
day.menuType ='dinner';
day.weekIds = trackMenuIds;
//工厂调用 - 每次运行,'trackMenuIds'数组都应该有
//从上一次运行中添加一个项目
menuFactory.matchMenuCriteria(day)
.then(function(response){
var randomItem = response.data [0];
day。 menuItem = {'_id':randomItem._id,'name':randomItem.name};
//将当前的id添加到数组中,用于下次运行
trackMenuIds。 push(randomItem._id);
});
});
};
当我追加trackMenuIds数组到当前行时,它没有被更新ID的。当我安慰它的时候,我可以看到它确实添加了它们,但是相信它是它的承诺的一部分,它不会尽早将更新后的数组传递给我的工厂调用。
我尝试了连锁承诺和其他方法,但似乎无法使其工作。很可能这归结于我对promise的缺乏经验,所以任何帮助都将不胜感激。
API正在并行进行。他们需要连续链接:
$ $ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $数组在每个迭代中更新并在工厂调用中使用
var trackMenuIds = [];
//初始空承诺
var promise = $ q.when();
angular.forEach(vm.planWeek.dinner,function(day){
//添加两个项目到当天(当前行)传递到工厂
day.menuType ='dinner';
day.weekIds = trackMenuIds;
//工厂调用 - 每次运行,'trackMenuIds'数组都应该有
//从上一次运行中添加一个项目
// CHAIN顺序
promise = promise.then(function(){
// RETURN API promise to chain
return menuFactory.matchMenuCriteria(day);
})。then(function(response){
var randomItem = response.data [0];
day.menuItem = {'_id':randomItem。 _id,'name':randomItem.name};
//将当前的id添加到要用于下次运行的数组
trackMenuIds.push(randomItem._id);
});
});
return promise;
};
上面的例子创建了一个初始的空承诺。 foreach循环会在每次迭代中将一个调用链接到异步API。
I have been doing lots of searching trying to find a solution, and believe it ultimately comes down the the promise as my data is returned but all at the end, where as I need it through each iteration.
I have the vm.planWeek.dinner that I loop through each row, and append 'menuType' and the 'trackMenuIds' array to it, which I then use in my MongoDB call for search criteria. This all works fine, but the key element, is with each factory call returned, I add the returned item's id to the 'trackMenuIds' array. The reason for this is, it builds an array of items I already have returned, so they can ignored in the next call, ie via $nin.
vm.reviewWeek = function () {
//Array to be updated over each iteration and used in factory call
var trackMenuIds = [];
angular.forEach(vm.planWeek.dinner, function (day) {
//Adds two more items to day(current row) to pass to factory
day.menuType = 'dinner';
day.weekIds = trackMenuIds;
//Factory call - each time this runs, the 'trackMenuIds' array should have
//one more item added from the previous run
menuFactory.matchMenuCriteria(day)
.then(function (response) {
var randomItem = response.data[0];
day.menuItem = {'_id': randomItem._id, 'name': randomItem.name};
//adds the current id to the array to be used for the next run
trackMenuIds.push(randomItem._id);
});
});
};
When I append the 'trackMenuIds' array to the current row, it hasn't been updated with any id's. When I console it, I can see it does infact add them, but believe as its part of a promise, it is not doing it early enough to pass the updated array into my factory call over each iteration.
I have tried chain promises and other means but just can't seem to get it to work. Quite possibly it comes down to my inexperience of promises, so any help would be greatly appreciated.
The calls to the factory asynchronous API are being made in parallel. They need to chained sequentially:
vm.reviewWeek = function () {
//Array to be updated over each iteration and used in factory call
var trackMenuIds = [];
//INITIAL empty promise
var promise = $q.when();
angular.forEach(vm.planWeek.dinner, function (day) {
//Adds two more items to day(current row) to pass to factory
day.menuType = 'dinner';
day.weekIds = trackMenuIds;
//Factory call - each time this runs, the 'trackMenuIds' array should have
//one more item added from the previous run
//CHAIN sequentially
promise = promise.then(function () {
//RETURN API promise to chain
return menuFactory.matchMenuCriteria(day);
}).then(function (response) {
var randomItem = response.data[0];
day.menuItem = {'_id': randomItem._id, 'name': randomItem.name};
//adds the current id to the array to be used for the next run
trackMenuIds.push(randomItem._id);
});
});
return promise;
};
The above example creates an initial empty promise. The foreach loop then chains a call to the asynchronous API on each iteration.
这篇关于AngularJS在每个循环中依次链承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!