Angular Promises Sequential Loop

I have the following dataset.

 $scope.orders = [
        { material: 'A', quantity: 32, orderNumber: 'dummy'},
        { material: 'A', quantity: 65, orderNumber: 'dummy'},
        { material: 'A', quantity: 86, orderNumber: 'dummy'},

        { material: 'B', quantity: 45, orderNumber: 'dummy'},
        { material: 'B', quantity: 68, orderNumber: 'dummy'},
        { material: 'B', quantity: 15, orderNumber: 'dummy'},

        { material: 'C', quantity: 11, orderNumber: 'dummy'}
    ];

      

I want to process (createOrder) orders grouped by material. After all orders for that particular material have been processed, I want to call another function (materialRun) that executes the material. After this function is successful, the next material needs to be processed (with its corresponding orders, etc.). All of these calls must be sequential since the backend cannot handle everything in parallel.

So, I'm looking for something like this:

material A: order 1 -> order 2 -> order 3 -> materialRun

when material Run from A is finished, start material B

material B: order 1 -> order 2 -> order 3 -> materialRun

when Run material from B is done start material C

...

I also need the result from each createOrder to update the order list

I am using angular promises, but I am open to suggestions. I hope this fiddle helps: http://jsfiddle.net/a1sp0ye2/

+3


source to share


2 answers


Below is the template for loops with asynchronous bodies i.e. the next iteration should only be performed after the asynchronous task completes. It works for promises in the Angular context, but can be generalized to any implementation of promises, I suppose:

/**
 * Loop the items array asynchronously.
 *
 * @param items - Array to iterate
 * @param doLoopBody - Callback that executes the body loop, returns promise
 */
function asyncLoop(items, doLoopBody) {
    var i = 0, d = $q.defer();

    nextIteration();

    return d.promise;

    function nextIteration() {
        if( i < items.length ) {
            doLoopBody(items[i], i, items).then(
                function() {
                    i++;
                    nextIteration();
                },
                onError
            );
        }
        else {
            d.resolve();
        }
    }

    function onError(reason) {
        d.reject(reason);
    }
}

      



Based on that, here is a rough implementation of your case (see browser console for output).

+2


source


I'm not sure if this can help you, but try using my code: jsfiddle

        $scope.promises = [];
        ordersByMaterial.forEach(function(order) {
            $scope.promises.push(createOrder(order));
        });

      



I tried to test it by creating $scope.logsCreateValue = [];

where I store random values ​​from Math.floor(Math.random() * 10);

See section console.log($scope.logsCreateValue);

, it should match the values ​​from$scope.orders[key].orderNumber = res[key].orderNumber;

0


source







All Articles