VenomOverflow
VenomOverflow

Reputation: 31

About Dart async/await.I used a piece of code to test,But the print result is not as expected

void main() {
  methodA();
  methodB();
  methodC('main');
  methodD();
}

methodA(){
  print('A');
}

methodB() async {
  print('B start');
  await methodC('B');
  print('B end');
}

methodC(String from) async {
  print('C start from $from');
  Future((){                
    print('C running Future from $from');
  }).then((_){
    print('C end of Future from $from');
  });
  print('C end from $from');
}

methodD(){
  print('D');
}

The print results are as follows:

A
B start
C start from B
C end from B
C start from main
C end from main
D
B end
C running Future from B
C end of Future from B
C running Future from main
C end of Future from main

What I don't understand is why C start from main and C end from main prints before B end?? That is why print('B end') has not been executed yet, methodC('main') has already been executed. I thought I understood async/await ,but until I came across this code.And I hope to get help

Upvotes: 1

Views: 158

Answers (2)

lrn
lrn

Reputation: 71623

What happens is:

  • The runtime system calls main.
  • main calls methodA.
  • methodA prints "A".
  • methodA returns.
  • main calls methodB.
  • methodB prints "B start".
  • methodB calls methodC("B").
  • methodC prints "C start from B".
  • methodC creates a future, f1, using the Future constructor. This schedules a timer t1.
  • methodC calls then on f1 which adds a listener on f1 and returns a future g1. (This future is ignored).
  • methodC prints "C end from B".
  • methodC, because it's async, returns a future, h1, and schedules a microtask m1 to complete that future with null.
  • methodB awaits for h1.
  • methodB, because it's async, returns a future k. (This future is ignored).
  • main calls methodC("main").
  • methodC prints "C start from main".
  • methodC creates a future, f2, using the Future constructor. This schedules a timer t2.
  • methodC calls then on f2 which adds a listener on f2 and returns a future g2. This future is ignored.
  • methodC prints "C end from main".
  • methodC, because it's async, returns a future, h2, and schedules a microtask m2 to complete that future with null. (The future is ignored).
  • main calls methodD.
  • methodD prints "D".
  • methodD returns.
  • main returns.
  • The microtask loop runs microtask m1, which completes future h1 with null.
  • methodB completes its await expression because h1 has completed.
  • methodB prints "B end".
  • methodB completes future k with null. Nobody is listening for that.
  • The microtask loop runs microtask m2, which completes future h2 with null. Nobody is listenting for that.
  • The microtask queue is now empty.
  • The event loop runs timer t1, which
    • prints "C running Future from B".
    • completes the f1 future with null.
    • invokes the then listener on f1 and.
    • prints "C end of Future from B".
    • completes the g1 future with `null. Nobody is listening.
  • The event loop runs timer t2, which
    • prints "C running Future from main".
    • completes the f1 future with null.
    • invokes the then listener on f1 and.
    • prints "C end of Future from main".
    • completes the g1 future with `null. Nobody is listening.
  • The event and microtask queues are now empty, and the program exits.

Upvotes: 2

Jay Mungara
Jay Mungara

Reputation: 7150

When you use await keyword then the further statements will not get executed until the current subroutine/statement flow gets executed.

For Ex:

methodB() async {
  print('B start');
  await methodC('B');
  print('B end');
}

Here, after print('B start') you called methodC('B') with await keyword. So, now print('B end') will get executed after all the statements and method of the methodC('B') gets executed. Till then print('B end') statement will wait for the execution of the methodC('B')

Upvotes: 1

Related Questions