I was playing around but I don’t understand why this won’t work? In theory, I thought it would but it just goes into an endless loop. Don’t run it, it will most likely lock up your computer.
glb = "original";
async function wait() {
await new Promise(resolve => setTimeout(resolve, 2000));
glb = "updated";
}
function f() {
wait();
var glb2 = "original";
while (glb2 == "original") {
glb2 = glb;
console.log("#### glb:" + glb);
}
console.log("#### DONE glb:" + glb);
}
f();
Why does glb2 never get updated?
Thanks!
3
Answers
Well friend, this happens because the "await()" function returns a promise, which doesn’t give time to update the variable to "updated". For that, you need to make the function "f()" as asynchronous also waiting for the execution of the function "await()" with the use of the reserved word "await", as follows:
That way you can avoid the infinite loop.
Good luck.
JavaScript runtime is single-threaded and based on an event loop that runs to completion, meaning each item in the event loop’s queue needs to be completed before the next one can be processed.
From MDN:
This means that in your code, the
while
loop blocks the event loop, preventing any other operation queued (such as the promise resolution from thewait
function) to be executed.This is also one of the reasons why
setTimeout
‘s delay is not guaranteed (they might actually take longer).This series of posts might be a better start to understand that than the MDN documentation IMO: ✨♻️ JavaScript Visualized: Event Loop
If you want a loop that ends when a global variable is set to a certain value from outside of the loop, you must introduce an element of asynchronousness into the loop, so that the outside world gets a chance to modify the global variable. The following example uses a function that recursively invokes itself after 100ms. (You could also use a delay of 0ms, but a
setTimeout
or similar must be involved.)Note that replacing the recursion with
is not "asynchronous enough" to allow the
setTimeout(..., 1000)
to finish in between.