Search code examples
javascriptpromisees6-promise

Javascript Promise executes in incorrect order from For Loop


I have created two JS functions. One with For Loop, and the second one prints a text after 1 second of delay. Then I am calling them like this.

    // Code block 1
    console.log("Function Begins");
    functionWithLoop().then(function (result) {
          console.log("Function Ends");
    });

    // Code block 2
    function functionWithLoop() {            
        return new Promise(function(resolve, reject)
        {   
            for (let loopcount = 1; loopcount <= 3; loopcount++) {                
                MyCustomPrintFunction(loopcount).then(function(resolve)
                {
                    console.log("After custom print function : index " + loopcount);
                });                
            } 
            resolve();             
        });
    }

    // Code block 3
    function MyCustomPrintFunction(text) {
        return new Promise(function(resolve, reject)
        {   
            setTimeout(() => {
                console.log("In custom print function " + text);
                resolve();
            }, 1000);                
        });            
    }

The Expectation is, the Console Log order will be like this:

Function Begins    
In custom print function 1
After custom print function : index 1
In custom print function 2
After custom print function : index 2
In custom print function 3
After custom print function : index 3
Function Ends

But the Console prints in this order:

Function Begins
Function Ends
In custom print function 1
After custom print function : index 1
In custom print function 2
After custom print function : index 2
In custom print function 3
After custom print function : index 3

Why the first then() statement is not waiting for the whole loop to complete? What I am doing wrong here?


Solution

  • In your for loop, you are creating new promises (MyCustomPrintFunction(loopcount)) that run independently of the surrounding promise, use async and await to run them sequentially:

    // Code block 1
    console.log("Function Begins");
    functionWithLoop().then(function (result) {
        console.log("Function Ends");
    });
    
    // Code block 2
    async function functionWithLoop() {
        for (let loopcount = 1; loopcount <= 3; loopcount++) {                
            await MyCustomPrintFunction(loopcount)
            console.log("After custom print function : index " + loopcount);                
        }
    }
    
    // Code block 3
    function MyCustomPrintFunction(text) {
        return new Promise(function(resolve, reject)
        {   
            setTimeout(() => {
                console.log("In custom print function " + text);
                resolve();
            }, 1000);
        });
    }