Synchronous delay in code execution

I have a code which needs to be executed after some delay say 5000 ms.Currently I am using setTimeout but it is asynchronous and i want the execution to wait for its return. I have tried using the following:

function pauseComp(ms) 
 {
     var curr = new Date().getTime();
     ms += curr;
     while (curr   < ms) {
         curr = new Date().getTime();
     }
 } 

But the code i want to delay is drawing some objects using raphaeljs and the display is not at all smooth. I am trying to use doTimeout plugin. I need to have a delay only once as the delay and code to be delayed are both in a loop. I have no requirement for a id so I am not using it. For example:

for(i; i<5; i++){ $.doTimeout(5000,function(){
         alert('hi');  return false;}, true);}

This waits for 5 sec befor giving first Hi and then successive loop iterations show alert immediately after the first. What I want it to do is wait 5 sec give alert again wait and then give alert and so on.

Any hints/ suggestions are appreciated!


Solution 1:

Variation on the accepted answer which is just as good as this one.

Also, I agree with the caveats of preferring setTimeout and asynchronous function calling but sometimes e.g., when building tests, you just need a synchronous wait command...

function wait(ms) {
    var start = Date.now(),
        now = start;
    while (now - start < ms) {
      now = Date.now();
    }
}

if you want it in seconds, divide start ms by 1000 on the while check...

Solution 2:

If you'd like to take advantage of the new async/await syntax, You can convert set timeout to a promise and then await it.

function wait(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("Done waiting");
      resolve(ms)
    }, ms )
  })
}  

(async function Main() {
  console.log("Starting...")
  await wait(5000);
  console.log("Ended!")
})();

Solution 3:

Synchronous wait (only for testing!):

const syncWait = ms => {
    const end = Date.now() + ms
    while (Date.now() < end) continue
}

Usage:

console.log('one')
syncWait(5000)
console.log('two')

Asynchronous wait:

const asyncWait = ms => new Promise(resolve => setTimeout(resolve, ms))

Usage:

(async () => {
    console.log('one')
    await asyncWait(5000)
    console.log('two')
})()

Alternative (asynchronous):

const delayedCall = (array, ms) =>
    array.forEach((func, index) => setTimeout(func, index * ms))

Usage:

delayedCall([
    () => console.log('one'),
    () => console.log('two'),
    () => console.log('three'),
], 5000)

Solution 4:

Using the new Atomics API, you can start synchronous delays without performance spikes:

const sleep = milliseconds => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds)

sleep(5000) // Sleep for 5 seconds

console.log("Executed after 5 seconds!")