0

I'm fairly new to NodeJs and understanding the concept of async/await. Please correct me if I'm wrong - await keyword blocks the code until it gets a resolved value. For example:

const sampleFunction = async () => {
      const result = await someAsynFunctionReturningPromise();
      console.log('Log is printed here!');
}  

In the above code, the compiler stops the code at 'const result = await someAsynFunctionReturningPromise();' until 'someAsynFunctionReturningPromise()' gets resolved, right?

With the above assumption, I tried the below setTimeout() code:

const sampleFunction = async () => {
  const result = await setTimeout(()=>{
        console.log('This is printed after 2 seconds');
  },2000);
  console.log('Log is printed here!');
}    

However, the above code doesnt await till setTimeout() is resolved, it skips to the next line, printing 'Log is printed here!'.

Can anyone please help me understand if my understanding is wrong?

Tony Mathew
  • 880
  • 1
  • 12
  • 35
  • Does this answer your question? [Does awaiting a synchronous function synchronously return a value?](https://stackoverflow.com/questions/53113281/does-awaiting-a-synchronous-function-synchronously-return-a-value) – Dan O Apr 17 '20 at 19:23
  • 1
    `setTimeout` is not "some async function returning a promise" like in the first example. – Aioros Apr 17 '20 at 19:24

3 Answers3

1

In order for await to work with setTimeout, setTimeout needs to return a promise. Please see this: How to make a promise from setTimeout

d3bgger
  • 339
  • 2
  • 12
1

You wrote your own answer. You wrote

await keyword blocks the code until it gets a resolved value

In your code you never resolved anything so of course it won't work

A setTimeout that resolves is

function wait(ms = 0) {
  return new Promise(function(resolve, reject) { 
    setTimeout(resolve, ms);
  };
}

or the terse version

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

Example

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

const sampleFunction = async () => {
  for(;;) {
    await wait(2000);
    console.log('time since page loaded:', performance.now() / 1000 | 0);
  }
};

sampleFunction();
gman
  • 100,619
  • 31
  • 269
  • 393
  • `setTimeout()` synchronously returns a timer handle, and `await`ing a non-Promise will resolve immediately. that's why OP's code snippet exhibits the described behavior. nothing is waiting forever here. – Dan O Apr 17 '20 at 20:18
1

This is where the event loop of node JS working comes in. In the first place your

someAsynFunctionReturningPromise()

is returning a promise where in the second code setTimeout() does not return you promise. Also when nodejs eventloop gets such a function like setTimeout() it will put it in callstack and then to taskqueue where it will wait for 2000ms and goes for the next line of execution, that is why it is printing

console.log('Log is printed here!');

when 2000ms are over the setTimeout will be kept from taskqueue to callstack and it will execute

console.log('This is printed after 2 seconds');
Yatin Gaikwad
  • 1,140
  • 1
  • 13
  • 23