AngularJS在forEach循环中顺序地链许诺

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

我有一个vm.planWeek.dinner,它遍历每一行,并将’menuType’和’trackMenuIds’数组附加到该行,然后在MongoDB中使用该数组查找搜索条件.一切正常,但是关键元素是返回的每个工厂调用,我将返回的项目的ID添加到“ trackMenuIds”数组中.原因是,它构建了一个我已经返回的项目数组,因此可以在下一个调用中忽略它们,即通过$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对其进行更新.当我对其进行控制台时,我可以看到它确实添加了它们,但是相信作为承诺的一部分,它没有尽早将更新的数组传递给每次迭代的工厂调用.

我已经尝试过链承诺和其他方式,但似乎无法使其发挥作用.这很可能归结于我对诺言的缺乏经验,因此任何帮助将不胜感激.

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

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的调用.

转载注明原文:AngularJS在forEach循环中顺序地链许诺 - 代码日志