0

I have a program, which is supposed to execute the first line and wait for two seconds then execute the second, and finally the third.

console.log("Before Execution...");
setTimeout(() => console.log("Between"), 2000);
console.log("After Execution...");

But the output I am getting is something like this:

Before Execution...
After Execution...
Between

I understand that it's because setTimeout() works asynchronously, but there must be way to do a real synchronous delay.

  • You can put the third console.log inside of your setTimeout callback `()=> {console.log("Between"); console.log("After execution");}`, using synchronous delay isn't advisable as it will block UI thread, so your page will freeze and be unresponsive – Nick Parsons Apr 24 '21 at 10:05
  • If your actual code is more complex, you can go for the promise-based approach with async/await, as shown in georg's answer – Nick Parsons Apr 24 '21 at 10:15

2 Answers2

3

No, it's not possible to make a synchronous delay. You have to use promises, like this:

const delay = n => new Promise(r => setTimeout(r, n));

async function main() {
    console.log("Before Execution...");
    await delay(1000);
    console.log("After Execution...");
}

main()

Theoretically, you could put the "after" part into the setTimeout callback, but I wouldn't recommend that. Callbacks are harder to follow and often result in spaghetti code.

georg
  • 211,518
  • 52
  • 313
  • 390
0

No setTimeout always asynchronous. But we can define our own custom timeout func and make it synchronous.

// Tell the browser that this function is asynchronous
async function myTimeoutFunc(delay) {
    // Await for the promise to resolve
    await new Promise((resolve) => {
        setTimeout(() => {
            // Resolve the promise
            resolve(console.log('Between'));
        }, delay);
    });
}

async function myMainFunc (){
  console.log("Before Execution...");
  await myTimeoutFunc(2000);
  console.log("After Execution...");
}

myMainFunc();
Thiwanka Wickramage
  • 782
  • 1
  • 10
  • 22
  • Thanks, but why are we awaiting ``myTimeoutFunc(2000)`` when we are not returning a promise? –  Apr 24 '21 at 10:17
  • myMainFunc func need to know which we are calling functions are asynchronous or synchronous. that why we need use await. – Thiwanka Wickramage Apr 24 '21 at 10:21
  • I've executed your code. Does it only wait only for promise execution, when we use await? –  Apr 24 '21 at 10:23
  • 1
    if you wrap your func with promise function its work sync or async way. if you want to run that func and wait for response need to use await. if you dont care about that func response you dont need to put await = – Thiwanka Wickramage Apr 24 '21 at 10:27
  • All right, got it. –  Apr 24 '21 at 10:28