Search code examples
javascriptfunctionpromisetimingcalling-convention

How to wait for function to stop before calling it again


I have had trouble trying to get my function to finish before calling it again. This is my code now:

function TypeAnimation(str, time)
{    
    var text = document.getElementById('loading');

    for (let i = 0; i < str.length; i++) {
        let k = i;
        setTimeout(function(){
            text.innerHTML += str.charAt(i); 
        }, time * (k + 1));
    }
}

function StartGame()
{
    TypeAnimation('first line of text', 50)
    TypeAnimation('next line of text but slower', 100)
}

window.onload = StartGame;

When doing this I get the output as finrset xlitne olf itenxte of text but slower.

I have tried promises by using the following code:

function TypeAnimation(str, time)
{    
    return new Promise((resolve) => {

        var text = document.getElementById('loading');

        for (let i = 0; i < str.length; i++) {
            let k = i;
            setTimeout(function(){
                text.innerHTML += str.charAt(i); 
            }, time * (k + 1));
        }

        resolve();
    });
}

function StartGame()
{
    TypeAnimation('first line of text', 50).then(TypeAnimation('next line of text but slower', 100))
}

window.onload = StartGame;

But when I do this I still get the same result

On top of this, I also tried the same thing but with with a different StartGame()

async function StartGame()
{
    await TypeAnimation('first line of text', 50)
    TypeAnimation('next line of text but slower', 100)
}

Once again, the same issue arises and I get the same output

If it helps, this is all created with an electron js app.


Solution

  • Your code doesn't work, because you resolve the promise before timeouts even happen

    The approach like this will make it easier

    async function TypeAnimation(str, time) {
      const text = document.getElementById('loading');
    
      for (let i = 0; i < str.length; i++) {
        text.innerHTML += str.charAt(i);
        await wait(time)
      }
    }
    
    async function StartGame() {
      await TypeAnimation('first line of text', 50)
      await TypeAnimation('next line of text but slower', 100)
    }
    
    StartGame()
    
    function wait(time) {
      return new Promise(r => setTimeout(r, time))
    }
    <span id="loading"></span>