Search code examples
node.jses6-promise

my ECMA 6 Promises do not resolve in sync way


I am trying to understand ES6 Promises (and promises in general) but things are not clear for me. I tried to get this code running :

var function1 = function() {
    console.log("function 1 has started")
}

var function2 = new Promise((resolve, reject) => {
    console.log("function2 has started");
    setTimeout(function() {
        console.log("function2 has ended")
        resolve();
    }, 3000) 
})

var function3 = new Promise((resolve, reject) => {
    console.log("function3 has started");
    setTimeout(function() {
        console.log("function 3 has ended")
        resolve()
    },2000)
})

var myFunc = function () { 
    function3.then(function2).then(function1())
}

myFunc();

The Output I expected :

function3 has started
//after 2 seconds
function3 has ended
function2 has started
//after 3 seconds
function2 has ended
function1 has started

The output I get :

function2 has started
function3 has started
function1 has started
//after 2 seconds
function3 has ended
//1 second more
function2 has ended

Could you explain me what I did wrong on my code ?


Solution

  • Two things to keep in mind:

    • When invoking a Promise constructor, the passed callback function always gets invoked IMMEDIATELY from inside of the constructor.
    • Callbacks that you pass to then() or catch() are NEVER invoked immediately.

    Therefore, in your scenario, the strings "function2 has started" and "function3 has started" are printed as the two Promises are construcuted.

    "function 1 has started" is printed immediately thereafter because you directly invoke it from within myFunc(). You probably meant to pass function1 without parenthesis like this:

    function3.then(function2).then(function1)
    

    In that case, function1 would only be called at the end (as you expected) once both promises have fulfilled.

    I think the sequence of the remaining two outputs is clear, The "ended" messages are printed as the setTimeout callbacks get called.

    The following produces the output you were expecting.

    var function1 = function() {
        console.log("function 1 has started")
    }
    
    var function2 = function () {
        return new Promise((resolve, reject) => {
            console.log("function2 has started");
            setTimeout(function() {
                console.log("function2 has ended")
                resolve();
            }, 3000);
        });
    };
    
    var function3 = function () {
        return new Promise((resolve, reject) => {
            console.log("function3 has started");
            setTimeout(function() {
                console.log("function 3 has ended")
                resolve()
            }, 2000);
        });
    };
    
    var myFunc = function () { 
        function3().then(function2).then(function1);
    }
    
    myFunc();