Search code examples
javascriptasync-awaites6-promisewait

async / wait in nested functions


I'm trying to display a nested countdown, implemented in two nested loops.

The full, working code can be found in this js.fiddle. Two relevant parts are the following:

function sleep(ms) 
{
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function main()
{
    while(true)
    {
      clearScreen();

        for (var i = 10; i > 0; i--) 
        {
            print(i);

            await sleep(1000);

            clearScreen();

            for (var j = 3; j > 0; j--) 
            {
                print(j);

                await sleep(1000);

                clearScreen();
            }
        }
    }
}

main();

This works as expected. However, when I try to refactor the most inner loop into a seperate function like this

async function innerLoop()
{
    for (var j = 3; j > 0; j--) 
    {
        print(j);

        await sleep(1000);

        clearScreen();
    }
}

and call this function inside main() the coutndown doesn't work as expected. (Corresponding code: js.fiddle).

How can I make async / await work when using it inside nested functions to implememt this? I want to avoid having everything in one big function.


Solution

  • innerLoop() is an async function so you need to await it on your call:

    var containerElement = document.getElementById("container");
    
    function print(string) {
      var textDiv = document.createElement("div");
      textDiv.textContent = string;
    
      containerElement.appendChild(textDiv);
    }
    
    function clearScreen() {
      containerElement.textContent = "";
    }
    
    function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    }
    
    async function main() {
      while (true) {
        clearScreen();
    
        for (var i = 10; i > 0; i--) {
          print(i);
    
          await sleep(1000);
    
          clearScreen();
    
          await innerLoop();  // <-- Await innerLoop()
        }
      }
    }
    
    async function innerLoop() {
      for (var j = 3; j > 0; j--) {
        print(j);
    
        await sleep(1000);
    
        clearScreen();
      }
    }
    
    main()
    <!DOCTYPE html>
    <html>
    
    <body>
    
      <div id="container"></div>
    
    </body>
    
    </html>