Search code examples
javascriptnode.jsasync-awaites6-promise

Equivelance between two different dynamic promise provider chains


I am wondering if the two code blocks are basically equivalent:

const executePromises = function(listOfProviders){

    let p = Promise.resolve(null);

    for(let i = 0; i < listOfProviders.length; i++){
       p = p.then(v => listOfProviders[i]());
    }

   return p;

};

I believe the above is basically equivalent to:

const executePromises = async function(listOfProviders) {

    for(let i = 0; i < listOfProviders.length; i++){
       await listOfProviders[i]();
    }

};

does anyone see a discrepancy?


Solution

  • No. They are not the same. Even if you return the promise as someone pointed out in comments.

    Difference:

    • When using async await with for-loop, it should be remembered that for loop goes to next iteration only when the awaited promise has been resolved in the current iteration.
    • On the other hand, when .then is used in a for-loop, that for-loop doesn't wait for the promise to resolve before going to the next iteration.

    I have tweaked your code to demonstrate this. Observe that Line A is being called at different point of time in each code snippet.

    Async await inside for-loop code:

    function createPromiseWhichResolveAfterOneSec(i) {
        return new Promise((resolve, reject)=>{
            setTimeout(()=>{
                console.log("About to resolve promise with value:",i);//Line A
                resolve(i);
            },1000)
        })
    }
    
    const executePromises = async function(listOfProviders) {
    
        let p;
        let i;
        for(i = 0; i < listOfProviders.length; i++){
            console.log("before", i);
            p = await createPromiseWhichResolveAfterOneSec(i);
            console.log("after", i);
        }
        console.log(i);
        return p;
    
    };
    
    
    let listOfProviders = [1,2,3,4,5];
    let promise = executePromises(listOfProviders);
    promise.then(value => console.log("this is the final value of promise chain:",value)).catch(()=>{});

    With then in for-loop:

    function createPromiseWhichResolveAfterOneSec(i) {
        return new Promise((resolve, reject)=>{
            setTimeout(()=>{
                console.log("About to resolve promise with value:",i);//Line A
                resolve(i);
            },1000)
        })
    }
    
    
    const executePromises = function(listOfProviders){
    
        let p = Promise.resolve(null);
    
        for(let i = 0; i < listOfProviders.length; i++){
            console.log("before", i);
            p = p.then(v => createPromiseWhichResolveAfterOneSec(i));
            console.log("after", i);
        }
    
        return p;
    
    };
    
    let listOfProviders = [1,2,3,4,5];
    let promise = executePromises(listOfProviders);
    promise.then(value => console.log("this is the final value of promise chain:",value)).catch(()=>{});