Synchronous loop in Promise all Synchronous loop in Promise all mongoose mongoose

Synchronous loop in Promise all


Without using await (which is not in node.js v6.11.2, but would make this simpler), a classic pattern for serializing a bunch of async operations that return a promise is to use a reduce() loop like this:

arr.reduce(function(p, item) {    return p.then(function() {        return saveInDatabase(item).then((myResult) => ... );    });}, Promise.resolve()).then(function() {    // all done here}).catch(function(err) {    // error here});

If you want to save all the results, you can use your .then(myResult => ...) handler to .push() the result into an array which you can access when done.

This will serialize all the calls to saveInDatabase(item) to it waits for the first one to be done before calling the second one, waits for the second one to be done before calling the third one, etc...

The default implementation here will stop if saveInDatabase(item) rejects. If you want to keep going (you don't say in your question), even when it gives an error, then you can add a .catch() to it to turn the rejected promise into a fulfilled promise.


In node.js v7+, you can use await in a regular for loop:

async function myFunc() {    let results = [];    for (let item of arr) {        let r = await saveInDatabase(item).then((myResult) => ... );        results.push(r);    }    return results;}myFunc().then(function(results) {    // all done here}).catch(function(err) {    // error here});

If you could run all the requests in parallel, then you could do that like this:

Promise.all(arr.map(item => {     return saveInDatabase(item).then((myResult) => ... );})).then(function(results) {    // all done here}).catch(function(err) {    // error here});

In any of these, if you don't want it to stop upon a rejection, then add a .catch() to your saveInDatabase() promise chain to turn the rejection into a resolved promise with some known value or error value you can detect.