1

In the following code the last line does not print ('end'):

function setTimeoutSync(fn, milli) {
    return new Promise((resolve) => {
        setTimeout(fn, milli);
    });
}

async function run () {
    console.log('start');
    await setTimeoutSync(() => { console.log('setTimeoutSync'); }, 3000);
    console.log('end');
}

run();

It is not that the script is exiting, because nothing I put after the await statement gets executed.

How can NodeJS just not execute statements in a function? Also, what's a good way to do a good old-fashioned synchronous wait in NodeJS? This question is actually more about the former than the latter.

HenryTK
  • 1,287
  • 8
  • 11

1 Answers1

1

Not sure if this is a typo but you forgot to call resolve so the next line after the await will execute:

function setTimeoutSync(fn, milli) {
  return new Promise((resolve) => {
    setTimeout(() => {
      fn()
      resolve()
    }, milli);
  });
}

async function run() {
  console.log('start');
  await setTimeoutSync(() => {
    console.log('setTimeoutSync');
  }, 3000);
  console.log('end');
}

run();

As for your question:

Can you explain how not calling resolve can result in the rest of the function not executing?...

Well async await uses generators and promise behavior:

The purpose of async/await functions is to simplify the behavior of using promises synchronously and to perform some behavior on a group of Promises. Just as Promises are similar to structured callbacks, async/await is similar to combining generators and promises.

A generator can yield results thus not terminating the execution context, and can continue it where it left off.

Basically your example could be written with Promise.prototype.then() callback:

function setTimeoutSync(fn, milli) {
  return new Promise((resolve) => {
    setTimeout(() => {
      fn()
      resolve()
    }, milli);
  });
}

async function run() {
  console.log('start');
  setTimeoutSync(() => {
    console.log('setTimeoutSync');
  }, 3000)
  .then((result) => {
   console.log('end');
  });
  
}

run();

So as you see, if we are not resolving, the callback to .then won't run.

Sagiv b.g
  • 30,379
  • 9
  • 68
  • 99
  • Thanks. Can you explain how not calling `resolve` can result in the rest of the function not executing? Is it causing the `run` function to return early? I would expect a runtime error if statements in a function were not executable. – HenryTK Jul 19 '19 at 09:48
  • 1
    It was not knowing that `generators` existed that confused me. Now it makes sense. Thanks! – HenryTK Jul 19 '19 at 10:08