Maxouille
Maxouille

Reputation: 2911

Future and async behavior is not the same and I don't get it

I'm facing a problem with async methods and Future in Dart.

I think I did/understood something wrong but I don't know what.

I'm trying to figure out the difference between Future and async and understand how the event loop works. I read the documentation and a lot of articles about that. I thought I understood so I tried to write some code that create a Future object with a sleep() call in it.

First, I tried with Future and I think it's behaving like it should:

main(List<String> arguments) {
    print('before future');
    test_future();
    print('after future');
}

test_future() {
    Future (() {
        print('Future active before 5 seconds call');
        sleep(Duration(seconds: 5));
        print('Future active after 5 seconds call');
    }).then((_) => print("Future completed"));
}

So this returns:

  1. print before future
  2. create a future object, put it in the event queue and return immediately
  3. print after future
  4. call the code of the future from the event queue
  5. print before 5 seconds
  6. wait 5 seconds
  7. print after 5 seconds*
  8. print future completed

I think all of this is normal.

Now, i'm trying to do the same with async. From the documentation, adding the async keyword to a function make it return a Future immediately.

So I wrote this:

main(List<String> arguments) {
   print('before future 2');
   test().then((_) => print("Future completed 2"));
   print('after future 2');
}

test() async {
    print('Future active before 5 seconds call');
    sleep(Duration(seconds: 5));
    print('Future active after 5 seconds call');
}

Normally, when calling test().then(), it should put the content of test() in the event queue and return a Future immediately but no. The behavior is this one:

  1. print before future 2
  2. call test() function (should return a future I think, but the code is executed right now)
  3. print before 5 seconds
  4. wait for 5 seconds
  5. print after 5 seconds
  6. print future completed 2
  7. print after future 2

Can someone explain if I did not use async properly or if there is something wrong ?

Best

Upvotes: 2

Views: 108

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 658205

You should be aware that sleep() just blocks the whole program. sleep() is not related in any way to the event loop or async execution. Perhaps you want to use instead:

await Future.delayed(const Duration(seconds: 5), (){}); 

async system calls do not block the isolate. The event queue is still processed, (continues immediately after invoking the system call). If you make sync system calls, they block like sleep.

There are often sync and async variants in dart:io of system calls like api.dartlang.org/stable/2.2.0/dart-io/File/readAsLinesSync.html. Even though sleep does not have the sync suffix, it's sync and no way to work around. You can use Future.delayed() as shown above to get the effect in an async way.

Upvotes: 3

Related Questions