I am new to Javascript and currently working on a website, that changes how it looks by itself over time.
One part of this page is a “Typewriter”, that writes out a text letter by letter. This is the code for this Typewriter:
function typeWriter(element, txt) { if (txt.length > 1) { element.textContent += txt.charAt(0); var newText = txt.slice(1,txt.length); setTimeout(typeWriter, 150 , element, newText); } else { element.textContent += txt.charAt(0); } }
Now I want to wait for the typewriter-function to finish with its text before doing another change to let’s say my background-color.
function runThis(){ var line1 = document.getElementById("line1"); typeWriter(line1, "This should be written first, before continuing"); document.body.style.backgroundColor = "blue"; }
To my understanding, the setTimeout makes my typewriter async, so if I do it as in the example above the third line of code will run as soon as the typewriter hits the first setTimeout.
I tried to realize this with the async/await terms and promises. But even after I resolve the promise, my “runThis” function won’t continue after the typewriter finishes.
function typeWriter(element, txt) { return new Promise (function(resolve,reject) { if (txt.length > 1) { element.textContent += txt.charAt(0); var newText = txt.slice(1,txt.length); setTimeout(typeWriter, 150, element, newText); } else { element.textContent += txt.charAt(0); resolve(); } }) } async function runThis() { var line1 = document.getElementById("line1"); await typeWriter(line1, "papupa"); console.log("waiting over") document.body.style.backgroundColor = "blue"; }
Can you please help me figure out what’s wrong here? Thank you very much
Advertisement
Answer
You can wrap the setTimeout
in a promise. This will allow you to use the async/await
syntax to express the intention of your code more clearly, almost as if it was running synchronously.
async function runThis() { var line1 = document.getElementById("line1"); await typeWriter(line1, "papupa"); document.body.style.backgroundColor = "blue"; } async function typeWriter(element, txt) { for (var i = 0; i < txt.length; i++) { element.textContent += txt[i]; // this is shorthand for txt.charAt(i) await pause(); } } function pause() { return new Promise(function(resolve, reject) { setTimeout(resolve, 150); }); }