Search code examples
javascriptcallbackwait

Waiting until a callback is executed


I want to wait until a callback is finished. I tried something like:

let wait = true;
setTimeout(() => {
    console.log("wait = false");
    wait = false;
}, 2000);
console.log("waiting");
while(true) {
    if(!wait) break;
}
console.log("finished waiting");

The only output is

waiting

And it doesn't proceed further. Even "wait = false" is not printed after 2 seconds. Can someone explain why this is happening?


Solution

  • Your while loop will never let setTimeout run. it's a synchronous infinite loop logic and will block the js thread till eternity.

    setTimeout is an asynchronous method and registers itself in event queue. When the main stack is done with it's work, event loop checks the queue for pending work and brings it back in main thread.

    In your case, main stack will never be free, because while loop will never complete.

    You can use Promise to do that.

    var promise = new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('timeout executed after 2s');
          resolve(); // resolve when setTimeout is done.
        }, 2000);
    });
    console.log('waiting');
    promise.then(_ => console.log("finished waiting")); // Use `.then` to do work after promise is resolved.

    Or you can do that just inside the callback of setTimeout

    var callback = function() { 
      console.log('finished execution');
      // all other work.
    }
    
    console.log('waiting');
    setTimeout(callback, 2000);

    Or use async-await. This gives the impression that the logic is synchronous by waiting for promise to resolve before moving ahead.

    (async function() {
      console.log('waiting')
      await new Promise((resolve, reject) => {
        setTimeout(_ => {
          console.log('setTimeout executed');
          resolve();
        }, 2000)
      })
      console.log('finished execution')
    })()