Search code examples
javascriptecmascript-6promisees6-promisechain

Why the promises chains does not work as expected (chaining tasks)


What are the advantages using the chain with '.then' if it does not work like a expected:

new Promise(function(resolve, reject) { 
    // A mock async action using setTimeout
    setTimeout(function() { resolve(10); }, 3000);
})

.then(function(num) { 
    console.log('first then: ', num); return num * 2; })

.then(function(num) { 
    setTimeout(function() { 
        console.log('second then: ', num); return num * 2; }, 500);
    })

.then(function(num) { 
    console.log('last then: ', num);
});

// RESULT!
// From the console:
// first then:  10
// last then:  undefined
// second then:  20

I was expecting for the following result:

// RESULT!
// From the console:
// first then:  10
// second then:  20
// last then:  40

Solution

  • The second then has to return another promise if you want the third then to fire after the timeout in the second then.

    This version of your code will give you the desired result:

    new Promise(function (resolve) { 
        setTimeout(function() {
        	resolve(10);
        }, 3000);
    })
    .then(function (num) { 
        console.log('first then: ', num); return num * 2;
    })
    .then(function (num) { 
        return new Promise(function (resolve) {
        	setTimeout(function () { 
                console.log('second then: ', num);
                resolve(num * 2);
            }, 500);
        });
    })
    .then(function (num) { 
        console.log('last then: ', num);
    });

    The reason why your code didn't work as expected was that the third then was invoked immediately after the second timeout started, with the result of the call to setTimeout, which is undefined.

    I looks like you expected the result you are returning from the callback of the second timeout to be somehow passed as result of the second then, but that's not the way it works.