Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is async required on methods that call async methods?

Consider this (textbook) sample dart code:

// Sequential processing using async and await.
main() async {
  await expensiveA();
  await expensiveB();
  doSomethingWith(await expensiveC());
}

I understand that await will wait for the result of the future "expensiveA" to complete before continuing.

But what I don't understand is why main() must itself be declared async? Apparently you have to do this or the program will not compile. But why can a synchronous method not await the result of asynchronous calls?

I understand this must be a newbie question but I have not been able to find an answer for this yet.

like image 500
user1283068 Avatar asked Aug 31 '17 09:08

user1283068


People also ask

Why async is needed?

Note: The purpose of async / await is to simplify the syntax necessary to consume promise-based APIs. The behavior of async / await is similar to combining generators and promises. Async functions always return a promise.

Should async methods be named async?

Naming ConventionBy convention, you append "Async" to the names of methods that have an async modifier. You can ignore the convention where an event, base class, or interface contract suggests a different name. For example, you shouldn't rename common event handlers, such as Button1_Click .

What happens when you call an async method?

The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.

Should you always await async methods?

If a method is declared async, make sure there is an await! If your code does not have an await in its body, the compiler will generate a warning but the state machine will be created nevertheless, adding unnecessary overhead for an operation that will actually never yield.


1 Answers

Before async/await, which was only added a while ago to Dart, you would have written like

main() {
  var result = expensiveA()
    .then((_) => expensiveB())
    .then((_) => expensiveC()); // the Future returned by expensiveC will be returned because `doSomethingWith` is not awaited in your code
  result.then(doSomethingWith);
  return result;
}

An async call returns a Future, and you can pass a function to it's then method to be called when the async call completes.

This code

main() async {
  await expensiveA();
  await expensiveB();
  doSomethingWith(await expensiveC()); // doSomethingWith is not awaited
}

get's rewritten to something similar to the code in the first code block, before it's executed.

This shows that async/await doesn't change the nature of the code, it only changes the syntax to something that looks more like sync code.

async is a marker that the code in the method needs to be rewritten, and this marker allows the use of await, without rewriting await would have no meaning.

async implicitly returns the last awaited Future, so that the caller is able to await the completion of this Future. Because a Future is returned, strong mode requires the return type to match.

like image 131
Günter Zöchbauer Avatar answered Oct 09 '22 18:10

Günter Zöchbauer