Brian Ogden
Brian Ogden

Reputation: 19242

What will be the output of this node/es6 code and why?

I was presented this coding question on a job application and I want to learn and understand, so here is the code question and then I will provide my interpretation and ask the SO community to elaborate/correct my interpretation:

async function someFunction() {
    console.log('someFunction'):
}

console.log('start');
someFunction();
console.log('end');

The output here is arguably unpredictable in my opinion, the order now, simply because we know the implementation of someFunction starts with a console.log will be:

I have run this code in my browser and I do see that it always runs in this order. I am just not sure as to the reason why.

Reading online, "forgetting" the await keyword for the execution of async someFunction the function will still execute asynchronously.

My reasoning is that, albeit someFunction is async and returns a promise, the first line of execution of someFunction will occur before console.log('end'). I am not sure why many developers think that these are good hiring questions, perhaps they are. I just find them to be trick questions that are not real world. In the real world, the promise returned by someFunction would be handled, for example:

console.log('start');
await someFunction();
console.log('end');

I would appreciate an explanation of this code please.

Upvotes: 0

Views: 291

Answers (1)

VLAZ
VLAZ

Reputation: 29116

The order here is completely deterministic it will always be start -> someFunction -> end:

async function someFunction() {
    console.log('someFunction');
}

console.log('start');
someFunction();
console.log('end');

This is because only an await will pause the execution of an async function. Any code before an await will be executed synchronously, while any code after an await will only run after the promise awaited is resolved:

async function someFunction() {
  console.log('someFunction - before await');
  
  await otherFunction();
  
  console.log('someFunction - after await');
}

async function otherFunction() {
  console.log('otherFunction');
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      console.log('promise resolved');
      resolve();
    }, 0);
});
}

console.log('start');
someFunction();
console.log('end');

This can come into play if you have non-trivial async functions that might do multiple actions and it matters what order they are in:

//sample shared variable
let counter = 1;

async function someFunction() {
  console.log('someFunction - before await counter is:', counter);
  
  let awaitResult = await otherFunction();
  
  console.log('someFunction - after await counter is: ', counter, '\nawaited function returned: ', awaitResult);
}

async function otherFunction() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(counter);
    }, 0);
});
}

someFunction();
counter += 1;

This is a dumbed down example but it showcases what can happen - if you read someFunction you could assume that counter has the same value both times. But that's not correct, since the mutation of the variable happens after the first read and before the second one. The await is what makes the difference.

Upvotes: 2

Related Questions