-3

I expected "asd" to print and the promise to resolve, but reality is different. The code gets stuck at while loop, and "getI" always returns 1, despite it being changed further several times through different means.

let i = 1;

function getI() {
    return i;
}

new Promise( resolve => {
    while(getI() === 1) {

    }

    console.log('asd');
    resolve();
})

i = 2;

setTimeout(() => i = 3, 1500);

new Promise(resolve => {
    i = 4;
    resolve();
})

What's the mechanism behind all this?

mrBomj
  • 3
  • 1
  • 1
    Your while loop blocks everything. – tkausl Jul 29 '23 at 21:45
  • 1
    Your `while` loop is going to clog up the event loop forever because none of the code that changes `i` can run. JS does not run multiple codepaths at the same time. This is called "run-to-completion" behavior. You need to yield to the event loop at some point for other chunks of code to ever get to run. https://exploringjs.com/es6/ch_async.html#:~:text=JavaScript%20has%20so%2Dcalled%20run,to%20worry%20about%20concurrent%20modification.. (to clarify, the code in a Promise constructor executes synchronously) – CollinD Jul 29 '23 at 21:46

1 Answers1

0

Some relevant facts for Javascript running in a browser or nodejs environment:

  1. Javascript runs your Javascript in a single thread
  2. Javascript is event driven
  3. Functions like setTimeout() trigger their callback to be called only via the event loop
  4. A while loop (that does not contain an await) is a blocking structure in Javascript and nothing else can run until that while loop finishes and returns control back to the event loop.

So, given all that, your while loop just runs forever. It hogs the interpreter and because it's hogging the interpreter and nothing else can run, the value of i never changes and thus your while loop can never complete and return control back to the event loop. The setTimeout() callback is sitting there waiting to run in the event loop, but never gets to run because the while loop never returns control back to the event loop. The while loop just sits there and spins forever since no code inside the while loop ever causes the value of i to change.

The basic concept in single threaded, event driven code is that the interpreter runs a piece of Javascript code until it returns. When it returns the interpreter goes back to the event loop to see what else is waiting to run, grabs the next event, calls its callback and similarly waits until it returns before it can then run the next event.

Events like timers are queued and cannot execute their callback until control is returned back to the event loop and until they get their turn in the event loop (as other things might run before them).

jfriend00
  • 683,504
  • 96
  • 985
  • 979