To iterate with async functions

I use for each to process a list, and I want this n item to be executed only when n-1 item ends:

var elements = ["stuff1", "stuff2", "stuff3"];

elements.forEach(function(element){
    someAsyncFunction(element, function(){
       console.log('do more stuff');
   });
});

      

I need them to wait for each other and execute in the correct order.

EDIT: I came across process.nextTick (), but I'm not sure if it guarantees expectation and order.

+3


source to share


2 answers


A good way is to use a promise library like Q or Bluebird and then implement promiseWhile

like this .

var Promise = require('bluebird');

var promiseWhile = function(condition, action) {
    var resolver = Promise.defer();

    var loop = function() {
        if (!condition()) return resolver.resolve();
        return Promise.cast(action())
            .then(loop)
            .catch(resolver.reject);
    };

    process.nextTick(loop);

    return resolver.promise;
};

      



Using:

var sum = 0,
    stop = 10;

promiseWhile(function() {
    // Condition for stopping
    return sum < stop;
}, function() {
    // Action to run, should return a promise
    return new Promise(function(resolve, reject) {
        // Arbitrary 250ms async method to simulate async process
        // In real usage it could just be a normal async event that 
        // returns a Promise.
        setTimeout(function() {
            sum++;
            // Print out the sum thus far to show progress
            console.log(sum);
            resolve();
        }, 250);
    });
}).then(function() {
    // Notice we can chain it because it a Promise, 
    // this will run after completion of the promiseWhile Promise!
    console.log("Done");
});

      

+2


source


Just store the elements in the array exactly the same as in your question. Then use elements.shift()

to fetch and remove the first item.



var elements = ["stuff1", "stuff2", "stuff3"];
(function next () {
    if (!elements.length) {
        return;
    }

    var element = elements.shift();
    someAsyncFunction(element, function (err, result) {
        next();
    });
})();

      

+4


source







All Articles