Home > Software design >  How can I set async for setTimeout in JavaScript
How can I set async for setTimeout in JavaScript

Time:10-10

    const delayTime = (time) =>
      setTimeout(() => {
        console.log("run after:", time);
      }, time);
    
    const runTime = async () => {
      await delayTime(1000);
      await delayTime(900);
    };
    
    runTime();

And actual result is:

run after: 900 run after: 1000

And expected result I want:

run after: 1000 run after: 900

CodePudding user response:

Async/await works with promises under the hood, so you need to return a promise from your delayTime function.

The Promise constructor accepts an executor function that is run synchronously (ie. immediately) with two callback functions as arguments: one to resolve the promise and another to reject the promise.

setTimeout and setInterval were added to JavaScript years before promises were widely understood, and are therefore not immediately compatible with promises: you need to "promisify" them.

To promisify a setTimeout expression you wrap it in a promise executor function and call the resolve callback function from inside the setTimeout callback .

    const delayTime = (time) =>
      new Promise((resolve) => setTimeout(() => {
        console.log("run after:", time);
        resolve();
      }, time));
    
    const runTime = async () => {
      await delayTime(1000);
      await delayTime(900);
    };
    
    runTime();

CodePudding user response:

It's more logical to have timeout function separately, and call action (log) in caller function:

// Timeout function
const timeout = ms => new Promise(resolve => setTimeout(resolve, ms));

// Caller function
const test = async () => {
  // Do all stuff here
  console.log(`starting...`);
  await timeout(3000);
  console.log(`3 sec passed...`);
  await timeout(5000);
  console.log(`8 sec passed, finishing.`);
}

// Run test
test();

CodePudding user response:

The reason your you see 900 hundred printed earlier is that the time out set for setTimeout is not constant. 900 milliseconds pass faster than 1000 millisecs, so hence 900 is printed earlier.

I have changed the method to pass the time-out delay with the respective message. Here is the implementation:

  const delayTime = ( delay, displayMessage) =>
          setTimeout(() => {
            console.log("run after:", displayMessage );
          }, delay);
        
        const runTime = async () => {
          await delayTime(1000, '1000');
          await delayTime(1000, '900');
        };
        
        runTime();

  • Related