I'm writing a short program to learn about Promises in JavaScript.
The goal of the program is to print a list of numbers (decreasing from 5 to 0) onto a HTML page, with a delay of 0.5s between each number. After the 0 is printed, a confirm box pops up and allows the user to print the same numbers again or stop.
Currently, the code below is mostly working but it acts very strangely during the first and second iteration of the inner loop (in the countdown() function) - between printing the first 5 and 4.
I've debugged it a lot in chrome dev to try to figure out what's happening, so I've included a step-by-step guide as to what the program is actually doing (or appears to be doing) beneath the code section, with the strange behaviours in bold.
This is an unmarked assignment for university and I managed to stump my professor so any help is much appreciated. Thanks in advance!!
// wait time for setTimeout
var wait = 500;
function timer(ms) {
return new Promise((res) => {
setTimeout(res, ms);
});
}
async function countdown() {
for (let i = 5; i >= 0; i--) {
document.write("<br>");
document.write(i);
console.log(i);
await timer(wait).then();
}
var c = confirm("Do you want to go again?");
document.write("<br>User Confirm:");
document.write(c);
console.log(c);
return c;
}
async function repeatRun() {
var prom = new Promise(async(res, rej) => {
r = await countdown();
if (r) {
res();
} else {
rej();
}
});
prom.then(
data => {
document.write("<br>RERUN");
console.log("RERUN");
repeatRun();
},
error => {
document.write("<br>ENDED");
console.log("ENDED");
}
);
}
repeatRun();
<!DOCTYPE html>
<html>
<head>
<title>Countdown</title>
</head>
<body>
<h1>Countdown</h1>
<p>Internet Applications Ex1.</p>
</body>
</html>
This is what my program is doing step by step:
displays HTML page title etc
enters
scripttagenters
repeatRun()creates Promise variable
promand enterscountdown()first iteration of
forloop (iei=5)5.1. prints
<br>and5usingdocument.write(), both are appended to the HTML body5.2. enters
timer()5.3. returns
new Promise5.4. this promise returns to
prom.then()insiderepeatRun()instead of toawait timer()call like i expectedI have tried this with and without
.then()afterwards and it does the same thing [this happens in one step on the Chrome debugger]exits the
scripttagre-enters the
scripttag, but not from the beginning: it returns to theforloop and decreasesicurrent HTML file:
<html> <head> <title>Countdown</title> </head> <body> <h1>Countdown</h1> <p>Internet Applications Ex1.</p> <script>...</scri pt> <br> "5" </body> </html>the next document.write() call, instead of appending
<br>to the HTML body, replaces the old HTML body with<br>, theheadtag is also erasedthe next document.write() appends
i(now 4) to the new HTML file current HTML file:<html> <head></head> <body> <br> "4" </body>
this is where the program starts to behave as expected 10. enters the
timer()function and then returns tocountdown()afterwards 11. loops as expected untili=0
11.1. `document.write()` appends to HTML body instead of rewriting
11.2. `timer()` function is called and returns to `countdown()` function afterwards
- after this loop, the confirm window pops up : I click "ok" and
trueis stored inc, printed usingdocument.write(), and returned and stored inr - since
r=true,ifsucceeds andres()is called - enters the
prom.then()and thendata =>anddocument.writeappends"<br>RERUN"to HTML body correctly - the
repeatRun()function is called recursively - creates new promise var and calls
countdown() - this time, the
forloop happens as expected (ie in step 11) fromi=5toi=0 - after the loop, I click "cancel" in the confirm window,
cis set tofalse, printed, and returned and stored inr - since
r=false,iffails andrej()is called - enters the
prom.then()and thenerror =>and document.write appends"<br>ENDED"to HTML body correctly - exits
scripttag