Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nodejs why is await only restricted to async functions?

Possible duplicate of await is only valid in async function.

I am new to NodeJS and I found the concept of async-await a bit confusing. After some reading and muddling around, this is my understanding of the same.

Suppose, I have a function sum like this.

function sum(a, b) {
  // print the numbers
  for (var i = 0; i < 100000; i++) {
    console.log(i);
  }
  // settimeout
  new Promise (resolve => {
    setTimeout(resolve, 1000);
  });
  return a+b;
}

function main() {
  let a = sum(5,2);
  console.log(a);
}

main();

It allocates a new thread for the timer and continues with the normal flow. It prints all the numbers first, returns a 7 and then waits for 1 second before exiting.

But now I want to execute the lines in the order they are written. It makes sense to put an await keyword before the timer Promise.

async function sum(a, b) {
  // print the numbers
  for (var i = 0; i < 100000; i++) {
    console.log(i);
  }
  // settimeout
  await new Promise (resolve => {
    setTimeout(resolve, 1000);
  });
  return a+b;
}

Issue 1: Here, I don't understand the obligation to put async to use await. Only putting async just makes the function return a Promise instead of a value. the flow is unchanged. It still prints all the number before printing 7.

Issue 2: I think the word async before a function misleads into thinking that the function calls would be asynchronous, though they are not. Any clarification with respect to design?

Issue 3:

  • In NodeJS, there is no concept of synchronous or asynchronous function call unless we have some blocking function like timer, remote requests and IO operations. That's where the concept of async-await comes into picture. Otherwise, it's just a single thread even if the program has Promises.
  • Putting async besides a function just makes it return a Promise instead of a value. It does not alter the program flow. Perhaps, it just puts some additional machinery to handle await (if any) just a guess!!.
  • async does not necessarily make any function (or its call) asynchronous. Call to function having async keyword will still be synchronous unless it contains another Promise that keeps it waiting. That's where await comes in.

Is my whole understading correct?

like image 558
Shashwat Avatar asked Nov 26 '18 06:11

Shashwat


1 Answers

Your function is not a great example, because the return value is not in any way connected to the await result. Because of this, the use of Promise is irrelevant, as the code could be rewritten without it. Let's change your function a bit, so that it actually generates the result inside the promise:

function sumLater(a, b) {
  return new Promise(resolve => {
    setTimeout(() => resolve(a+b), 1000);
  });
}

async function sum(a, b) {
  // print the numbers
  for (let i = 0; i < 100000; i++) {
    console.log(i);
  }
  // settimeout
  let result = await sumLater(a, b);
  // using the awaited result
  console.log("The awaited result is", result);
  return result;
}

async significantly changes the way the function is executed internally. For one thing, no function using a promise can ever return a value that is generated inside the promise. In the same way, no function that contains await can return anything generated from await onwards without it being wrapped in a promise. The reason for this is the lack of time travel in current computational architectures. If a function could now return a result of an operation that will complete two hours later, it would be a rather impressive breakthrough.

async is as much a signal to the JavaScript engine that the function will be executed in this special way, as well as to human code readers that it returns a Promise, not the returned value (unless the returned value was already a promise in the first place, and did not need wrapping).

Most of your issues are due to a terminological confusion. Don't get hung up on literal meaning of the terminology. Nothing in JavaScript (except Web Workers) is simultaneous, and at the first glance simultaneous and synchronous should be synonyms. In JavaScript, synchronous means "executes entirely within the same task", and asynchronous means "causes a new task to be placed on the execution stack", more or less, as far as I see it. Seen from this angle, async does mean that the function will be asynchronous, for the meaning "asynchronous" has in JavaScript.

like image 142
Amadan Avatar answered Oct 01 '22 01:10

Amadan