AngularJS在每个循环中依次链承诺 [英] AngularJS Sequentially Chain Promises in forEach Loops

查看:121
本文介绍了AngularJS在每个循环中依次链承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在进行大量的搜索,试图找到一个解决方案,并相信它最终落在了承诺,因为我的数据返回,但最终,我需要通过每个迭代。$ /

我有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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆