Search code examples
javascriptnode.jsdelayes6-promisechaining

Promise chain with delay does not work


I need to chain promises back to back with a delay in between but it's not working. All the promises seem to resolve at the same time.

Here is a simplified example that does not seem to work.

function delayPromise() {
    const delay = 500;
    return new Promise(function(resolve, reject){
        setTimeout(resolve, 1000);
    });
}

const data = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
const promiseChain = Promise.resolve();

data.forEach(function(datum) {
    promiseChain
    .then(delayPromise)
    .then(delayPromise)
    .then(function(){
        // all of these are logged at the same time!
        console.log(`Datum logged: ${datum}`);
    });
});

Thanks


Solution

  • They are all logged at the same time because you are always chaining off of the base promise, promiseChain, without re-assigning it. That is, since you never re-assign that value, you're always starting a new chain from the same Promise.resolve.

    To change that, just make sure to reset the promiseChain variable with the new promise you get from the .then chain you set up. EG:

    promiseChain = promiseChain
        .then(delayPromise)
        // ... so on
    

    Make sure promiseChain is declared with let or that won't work

    Here's your example with that fix. Note that now they all log with a delay in between each:

    function delayPromise() {
        const delay = 500;
        return new Promise(function(resolve, reject){
            setTimeout(resolve, 1000);
        });
    }
    
    const data = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
    let promiseChain = Promise.resolve();
    
    data.forEach(function(datum) {
        promiseChain = promiseChain
        .then(delayPromise)
        .then(delayPromise)
        .then(function(){
            // These are all logged with a delay between each!
            console.log(`Datum logged: ${datum}`);
        });
    });