AngularJS Sequentially Chain Promises in forEach Loops

前端 未结 2 1813
眼角桃花
眼角桃花 2021-01-23 14:35

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

相关标签:
2条回答
  • 2021-01-23 14:52

    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.

    0 讨论(0)
  • 2021-01-23 15:09

    You can use $q.all to handle multiple asynchronous call. Once all promise done execute, loop through raw Http promise and then push the data to the new array

    vm.reviewWeek = function () {
    
        //Array to be updated over each iteration and used in factory call
        var trackMenuIds = [];
    
        var dinnersPromise = [];
    
        vm.planWeek.dinner.forEach(function (day, ind) {
            //Adds two more items to day(current row) to pass to factory
            day.menuType = 'dinner';
            day.weekIds = trackMenuIds;
            dinnersPromise.push(menuFactory.matchMenuCriteria(day));
        });
    
        $q.all(dinnersPromise).then(function (arr) {
            angular.forEach(arr, 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);
             });
        });
    }
    
    0 讨论(0)
提交回复
热议问题