skip to Main Content

I had code below from javascript.info async/await tutorial and I noticed it has used new Promise next to await, this is the cut from the code:

await new Promise((resolve, reject) => setTimeout(resolve, 3000));
img.remove();

link to code

so it’s possible to type this code as below:

 await setTimeout(()=>{img.remove()}, 3000));

so I’m wondering what’s the necessity to use new Promise next to await keyword(while we eliminate .then() and .catch() with await and try...catch but I’ve seen new Promises get used alongside the await)?

p.n: I thought maybe it gets used when we have conditions for rejection and success inside new Promise but in this example we have no condition and still it’s used.

2

Answers


  1. so it’s possible to type this code as below:

    await setTimeout(()=>{img.remove()}, 3000));
    

    That is syntactically valid, but it’s not going to do what you probably want. await only works with promises. setTimeout does not return a promise, it returns an id of the timeout. If you await something that isn’t a promise the code will move on immediately1.

    So this will set up a timeout for 3 seconds, then move on to all the rest of your code. Any of that code that was expecting the image to have been removed will be operating under a false assumption and thus may have bugs.

    let removed = false
    function fakeRemove() { 
      console.log('removing')
      removed = true 
    }
    
    async function example () {
      console.log('before the await', removed);
      await setTimeout(() => { fakeRemove() }, 3000);
      console.log('after the await', removed);
    }
    
    example();

    Maybe you don’t have any code that cares if the image has been removed, but in that case you can just do the timeout without await.

    In comparison, when you create the promise, now the await can be effective. All the code that comes after will be paused until those 3 seconds have elapsed

    let removed = false
    function fakeRemove() { 
      console.log('removing')
      removed = true 
    }
    
    async function example () {
      console.log('before the await', removed);
      await new Promise((resolve, reject) => setTimeout(resolve, 3000));
      fakeRemove()
      console.log('after the await', removed)
    }
    
    example()

    1) technically the await will queue up a microtask, and it must wait for that microtask to execute. But that just requires waiting for the remaining synchronous code in the call stack and other microtasks. It will not wait 3 seconds.

    Login or Signup to reply.
  2. await creates a new microtask for the code following it (and its left part) which will be executed after the code at its right is resolved. Usually it’s a promise but it could be any value. Indeed new Promise creates a new Promise which await waits to be resolved. So no wonders here. But any non-promise value is treated as a resolved promise and the microtask is created anyway. I suggest to refer to MDN, but

    1. read about the event loop and microtasks
    2. only then read about promises
    (async()=>{
      queueMicrotask(() => console.log('microtask'))
      await 1;
      console.log('await');
    })()

    In your second example your setTimeout() is executed before await so the await doesn’t affect it, you can remove it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search