Home > Blockchain >  Confusion in Dart's async await
Confusion in Dart's async await

Time:10-10

I have a confusion in understanding Dart's async/await functionality. Most tutorials use the following example:

Future<String> createOrderMessage() async {
  var order = await fetchUserOrder();
  return 'Your order is: $order';
}

Future<String> fetchUserOrder() =>
    // Imagine that this function is
    // more complex and slow.
    Future.delayed(
      const Duration(seconds: 2),
      () => 'Large Latte',
    );

Future<void> main() async {
  print('Fetching user order...');
  print(await createOrderMessage());
}

I understand that the fetchUserOrder function returns a Future. Anyone who calls this function will immediately get a Future object as a result but this Future object may not have the real result value at that time. It will be filled up in "future".

Now, the createOrderMessage function calls: await fetchUserOrder(); This means, the control will wait till fetchUserOrder() returns a completed/non-empty Future. Am I right here? Is this what await does?

If that is correct, it means, the createOrderMessage function is essentially synchronous now because it won't return until the Future returned by fetchUserOrder is filled. Thus, the order variable in this function is initialized with a completed Future. Then why does this function need the "async" keyword in its function declaration? What does it signify?

Second confusion is if Dart is single threaded, when and how exactly is an async function executed? If I invoke multiple method calls that return Futures like this without await:

...
Future<A> fa = getA();
Future<B> fb = getB();
Future<C> fa = getC();
...

Will the functions getA, getB, and getC be executed sequentially in the background or they will be executed "in parallel" somehow?

CodePudding user response:

Now, the createOrderMessage function calls: await fetchUserOrder(); This means, the control will wait till fetchUserOrder() returns a completed/non-empty Future. Am I right here? Is this what await does?

Yes. the await keyword means you get the completed T instead of Future<T> in return. So:

var a = fetchUserOrder(); // Type of a: Future<String>
var b = await fetchUserOrder(); // Type of b: String

When you use await, you tell the code to await the completion of the process and get the actual result. But without await, the stream is in the future and is in process until you await it somewhere else.

why does this function need the "async" keyword in its function declaration?

It's a rule to specify long-running functions. So when a function awaits for a long running process to complete, the function itself is also a long-running process. Why? Because it's waiting for another one to complete.

Therefore, you need to specify async for that as well. When another function is calling this one, it also knows this one might be long-running.

In short, every awaitable function needs to be in an async function.

Second confusion is if Dart is single threaded, when and how exactly is an async function executed?

You're mixing the concept of parallelism with asynchronous. An async process does not have to be done in multi thread. Async processes can be one one at time, but in a different order in compare to synchronous code. Take a look at this article which explains asynchronous in a single thread.

CodePudding user response:

Now, the createOrderMessage function calls: await fetchUserOrder(); This means, the control will wait till fetchUserOrder() returns a completed/non-empty Future. Am I right here? Is this what await does?

If that is correct, it means, the createOrderMessage function is essentially synchronous now because it won't return until the Future returned by fetchUserOrder is filled. Thus, the order variable in this function is initialized with a completed Future.

await allows asynchronous functions to have the appearance of synchronous functions by allowing asynchronous code to be structured very similarly to synchronous code. In your example, it's syntactic sugar for registering a Future.then() callback and immediately returning:

Future<String> createOrderMessage() {
  var future = fetchUserOrder().then((order) {
    return 'Your order is: $order';
  });
  return future;
}

await defers execution of the rest of that function; it does not wait and block execution of your entire thread. Your program will continue running its event loop, possibly allowing other asynchronous operations to make progress.

Will the functions getA, getB, and getC be executed sequentially in the background or they will be executed "in parallel" somehow?

As I mentioned in comments, it depends on how getA, getB, and getC are implemented. They could run in parallel, such as if they run in separate Dart isolates or in separate threads in the Dart VM/runtime.

  •  Tags:  
  • dart
  • Related