AngularJS 在 forEach 循环中按顺序链接 Promise [英] AngularJS Sequentially Chain Promises in forEach Loops

查看:39
本文介绍了AngularJS 在 forEach 循环中按顺序链接 Promise的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在进行大量搜索以试图找到解决方案,并相信它最终会在我的数据返回时兑现承诺,但最终会在每次迭代中都需要它.

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.

我有 vm.planWeek.dinner 循环遍历每一行,并将menuType"和trackMenuIds"数组附加到它,然后我在我的 MongoDB 调用中使用它来搜索搜索条件.这一切都很好,但关键是每个工厂调用都返回,我将返回的项目的 id 添加到trackMenuIds"数组中.这样做的原因是,它构建了一个我已经返回的项目数组,因此它们可以在下一次调用中被忽略,即通过 $nin.

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);
          });
     });
};

当我将 'trackMenuIds' 数组附加到当前行时,它没有更新任何 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.

推荐答案

对工厂异步 API 的调用是并行进行的.他们需要按顺序链接:

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;
};

上面的例子创建了一个初始的空承诺.然后 foreach 循环会在每次迭代时链接对异步 API 的调用.

The above example creates an initial empty promise. The foreach loop then chains a call to the asynchronous API on each iteration.

这篇关于AngularJS 在 forEach 循环中按顺序链接 Promise的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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