Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

node.js promise: then() of promise nested inside a then() chain doesn't get resolved

Writing a demo script to understand promises I nested multiple promises (using promises.all() to proceed after all promises are resolved) inside a then(). The then()s of the nested promises do not get resolved:

var Promise = require("bluebird");

var array = [];

// push promises onto array
new Promise(function(resolve, reject) {
    setTimeout(function() { 
        for (var i = 5 - 1; i >= 0; i--) {
            array.push(returnapromise());
            console.log("pushed promise number", i, "onto array");
        }
        resolve();
    }, 300);
})

.then(function() {
    new Promise.all(array).then(function() {
        console.log("\nall done\n");
    });
});

// function that returns a promise
var returnapromise = function() {
    return new Promise(function(yolo) {

        new Promise(function() {
            setTimeout(function() { 
                console.log("async function within nested promise");
            }, 200);
        })

        .then(function() {
            setTimeout(function() { 
                console.log("async function within then one")
            }, 100);
        })

        .then(function() {
            setTimeout(function() { 
                console.log("async function within then two")
                yolo();
            }, 50);
        });

    }) // eof returned promise

}; // eof returnapromise()

However the desired goal can be achieved using callbacks inside the nested promise, like this:

var Promise = require("bluebird");

var array = [];

// push promises onto array
new Promise(function(resolve, reject) {
    setTimeout(function() { 
        for (var i = 5 - 1; i >= 0; i--) {
            array.push(returnapromise());
            console.log("pushed promise number", i, "onto array");
        }
        resolve();
    }, 300);
})

.then(function() {
    new Promise.all(array).then(function() {
        console.log("\nall done\n");
    });
});

// function that returns a promise
var returnapromise = function() {
    return new Promise(function(yolo) {

        new Promise(function() {
            setTimeout(function() { 
                console.log("async function within nested promise");
                one()
            }, 200);

            var one = function() {
                setTimeout(function() { 
                    console.log("cb one")
                    two();
                }, 100);
            };

            var two = function() {
                setTimeout(function() { 
                    console.log("cb two")
                    yolo();
                }, 50);
            };

        }) // eof nested promise

    }) // eof returned promise

}; // eof returnapromise()

How can I write nested promises which's then()s actually get resolved?

like image 433
r0bs Avatar asked Jan 10 '16 23:01

r0bs


1 Answers

In your first version of returnapromise(), you create two promises, one nested inside of the other.

The inside promise is never resolved (there is no code to ever resolve it). As such, it never calls its .then() handlers which means that the yolo() function is never called which means the outer promise is never resolved. So, it is just stuck forever.

You can fix that by resolving the inner promise in that first setTimeout(), then then that still leaves the second setTimeout() disconnected from the whole promise chain.

You can rewrite returnapromise() like this:

function delay(t, val) {
    return new Promise(function(resolve) {
        setTimeout(function() {
            console.log(val);
            resolve(val);
        }, t);
    });
}

// function that returns a promise
var returnapromise = function() {
    return delay(200, "async function within nested promise").then(function() {
        return delay(100, "async function within then one");
    }).then(function() {
        return delay(50, "async function within then two");
    });
}; // eof returnapromise()

Working demo: https://jsfiddle.net/jfriend00/k1q60Lep/

like image 97
jfriend00 Avatar answered Sep 18 '22 07:09

jfriend00