Mindaugas Bernatavičius
Mindaugas Bernatavičius

Reputation: 3909

Nodejs: .then() statement does not execute after Promise.all()

I'm using nodejs Mongo driver and I want to backup some small collections and insert some data into one collection.

The flow that I came up with is:

However this does not work as expected and I never get to the .then() statement that should execute after Promise.all().

Question: is this the correct way to handle this situation and what should I do to reach the .then() statement that should execute after Promise.all(). I think there might be a more elegant approach or solution. Thanks in advance.

    var backupCollection = function(collection){
        let backup_coll = collection + "_bak";
        return new Promise((resolve, reject) => {
            console.log("About to backup current " + collection + " collection");
            db.createCollection(backup_coll, function(err){
                if(err) throw err;
                // some logic to backup the collections
                });
            });
        });
    }

    for(i = 0, len = backupCollArr.length; i < len; i++){
        var cb = backupCollArr[i];      
        backupProms.push(backupCollection(cb));
    }

    Promise.all(backupProms).then(function(){
        return new Promise((resolve, reject) => {
            for (var i = 1; i <= iterations; i++){
                rand1 = polluter_prefix + Date() + Math.random();
                guid1 = genGUID();
                db.collection(insertColl).insert({
                // code to add data
                });
            }
        });
    }).then(function(){
        db.close(function(){
            console.log("Close connection");
        });
    });

Upvotes: 0

Views: 1599

Answers (1)

Francois
Francois

Reputation: 3080

You are never nor resolving nor rejecting your Promises. Here is an example of working solution:

var backupCollection = function(collection){
    let backup_coll = collection + "_bak";

    return new Promise((resolve, reject) => {
        console.log("About to backup current " + collection + " collection");
        db.createCollection(backup_coll, function(err){
            return err ? reject(err) : resolve();
        });
    });
}

for(i = 0, len = backupCollArr.length; i < len; i++){
    var cb = backupCollArr[i];      
    backupProms.push(backupCollection(cb));
}

Promise.all(backupProms)
.then(function(){
   return;
});

Promise.allwill resolve all the promises in an Array, if Promises are never resolved, it will wait, if all Promises succeeds it will call the .then, if one Promise fails it will call the .catch.

In your case, it is never resolving because you are never calling resolve(), also note that in a Promise chain, meaning in the .then or .catch you dont have to return a Promise, you can return anything and continue with .then, if it throws an error it will be caught in the .catch. But if you have an asynchronous call, you must return a Promise. Here is an example:

Promise.all([Promise.resolve(true), Promise.resolve(false)])
.then((result) => {
    console.log(result); // [true, false]
    // I want to return the result of an async call with callback
    // I have to return a new Promise
    return new Promise((resolve, reject) => {
         someAsyncCall((err, result) => {
            return err ? reject(err) : resolve(true);
         });
    });
})
.then((result) => {
    console.log(result) // true
    throw new Error('some error');
})
.catch((error) => {
    // my error is caught here
})

Upvotes: 1

Related Questions