0

    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

5
  • Wrap delayTime in a promise: const delayTime = time => { return new Promise(resolve => { setTimeout(() => { console.log('run after:', time); resolve(); }, time); }); }; Commented Oct 9, 2022 at 12:32
  • and resolve promise with setTimeout Commented Oct 9, 2022 at 12:32
  • Why do we need add new Promise. I think setTimeout&Interval is a Promise. I'm confusing about it. Can you explain for me, thank you ^^ Commented Oct 9, 2022 at 12:39
  • 1
    @LuânNguyễnThế No, setTimeout() and setInterval() do not create a promise Commented Oct 9, 2022 at 12:53
  • I got it, thank you^^ Commented Oct 9, 2022 at 13:02

3 Answers 3

4

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();

Sign up to request clarification or add additional context in comments.

20 Comments

Doesn't using resolve make the DelayTime synchronous? and why Pollute the async/await with promises? The whole point of using async/await is to act as an alternate to the promises pattern.
If you're correct then I suppose your answer will be upvoted and selected as the answer.
@HaroonAzharKhan No, using resolve() does not make the function synchronous. Async-await is just a syntactic abstraction of promises, it only works with promises and if the function you're calling doesn't return a promise (which setTimeout doesn't, it uses a callback) you have to wrap it in your own promise.
It's so clear. I got it, thank youuu^^
@HaroonAzharKhan But setTimeout is not an async function, so it does not return a promise. Even if you resolve a promise immediately, that just adds it to the event queue and the following code only gets executed once the thread is free and starts to process the event queue, meaning it's still asynchronous. That isn't even what's happening here though since resolve() is called in the callback to setTimeout(), i.e. not immediately.
|
1

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();

Comments

-1

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();

21 Comments

Yah, but I wanna try async/await in the different time, thank you ^^
Then the order will change, why expect it to be the way you wanted?
This doesn't do what OP is after, it should log 1000after ~1s and then log 900 after 900m/s. The use of async/await here is inncorrect, as you should only use await on a thenable (ie: a Promise), using it on something that isn't a thenable doesn't do much (you'll see that if you remove async/await you'll get the same result). At the moment your code queues two timeouts in parallel that then complete and execute at the same time.
@NickParsons is that possible? to have a message with a delay of 900ms display before a message with a delay of 1000 ms? I gave him an answer for why his code didn't give the expected output and changed it to how that can be achieved. Not sure if what he is trying to do is achievable in reality
@HaroonAzharKhan It's quite simple, if you need a promise but don't have one, you have to create one. That doesn't make it inconsistent. You have to think of the handling of promises and the creation of promises as two separate things. Async-await only handles promises, sure it creates a promise implicitly when a function is declared as async but this promise doesn't accomplish anything unless there's an existing promise that controls the execution of code.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.