Skip to content
ArtemMikhaylov edited this page Jul 29, 2020 · 22 revisions

Page Navigation

Future

Explained from old android java point of view

Here are some examples:

We put a function (a task) in the constructor of Future, and this task is added to the queue of current Isolate (Thread). Then, when previous tasks in the queue (in this case only a running one) are done, this one executes in the same thread. It is similar to Handler.post(new Runnable() { public void run() {}}) in android java. But the Future is not the same as Handler!

/* OUTPUT:
I/flutter (25763): main: isolate main; process: 25763
I/flutter (25763): inFuture: isolate main; process: 25763
*/
    final myFuture = Future(() {
      print('inFuture: isolate ${Isolate.current.debugName}; process: $pid');
      return 12;
    });
    print('main: isolate ${Isolate.current.debugName}; process: $pid');

Another examples that shows that Dart executes one operation at a time, one after the other meaning that as long as one operation is executing, it cannot be interrupted by any other Dart code.

/* OUTPUT: (future task waits)
I/flutter (23585): main: isolate main; process: 23585
I/flutter (23585): inFuture: isolate main; process: 23585
*/
    final myFuture = Future(() {
      print('inFuture: isolate ${Isolate.current.debugName}; process: $pid');
      return 12;
    });

    int now = DateTime.now().millisecondsSinceEpoch;
    bool keepCycling = true;
    int step = 1000000;
    int i = 0;
    while (keepCycling) {
      i++;
      if (i > step) {
        i = 0;
        if (now + 3000 < DateTime.now().millisecondsSinceEpoch) {
          keepCycling = false;
        }
      }
    }
    print('main: isolate ${Isolate.current.debugName}; process: $pid');

In next example the future operation executes just after. Doesn't wait one second more, cause it is already at least 2 seconds passed after Future task was placed to queue.

/*  )
I/flutter (23585): main: isolate main; process: 23585
I/flutter (23585): inFuture: isolate main; process: 23585
*/
    final myFuture = Future.delayed(new Duration(seconds: 1),() {
      print('inFuture: isolate ${Isolate.current.debugName}; process: $pid');
      return 12;
    });

    int now = DateTime.now().millisecondsSinceEpoch;
    bool keepCycling = true;
    int step = 1000000;
    int i = 0;
    while (keepCycling) {
      i++;
      if (i > step) {
        i = 0;
        if (now + 3000 < DateTime.now().millisecondsSinceEpoch) {
          keepCycling = false;
        }
      }
    }
    print('main: isolate ${Isolate.current.debugName}; process: $pid');

waits 3 more seconds

/*
I/flutter (23585): start cycling 1581593522458
I/flutter (23585): done with main at: 1581593525469
I/flutter (23585): main: isolate main; process: 23585
I/flutter (23585): Executing the future delayed: 1581593528463
I/flutter (23585): inFuture: isolate main; process: 23585
*/
    final myFuture = Future.delayed(new Duration(seconds: 6),() {
      print('Executing the future delayed: ${DateTime.now().millisecondsSinceEpoch}');
      int process = pid;
      String currentIsolate = Isolate.current.debugName;
      print('inFuture: isolate $currentIsolate; process: $process');
      return 12;
    });

    int now = DateTime.now().millisecondsSinceEpoch;
    print('start cycling ${DateTime.now().millisecondsSinceEpoch}');
    bool keepCycling = true;
    int step = 1000000;
    int i = 0;
    while (keepCycling) {
      i++;
      if (i > step) {
        i = 0;
        if (now + 3000 < DateTime.now().millisecondsSinceEpoch) {
          keepCycling = false;
        }
      }
    }
    print('done with main at: ${DateTime.now().millisecondsSinceEpoch}');
    print('main: isolate ${Isolate.current.debugName}; process: $pid');

A Future represents a computation that doesn’t complete immediately. Where a normal function returns the result, an asynchronous function returns a Future, which will eventually contain the result. The future will tell you when the result is ready.

Future - is like callback given to you by the execution of the async method.

A future can be in one of two states: uncompleted or completed.

IMPORTANT: despite that returning type is declared as Future, we don't return a Future in the method body itself. We return the result value. But from outside function actually returns Future.

It's like we pass a callback object to an asynchronous method. But here async method returns callback object itself at once and then executes code inside its body, and the body returns a value that callback expects, passing it to the callback.

The async function executes only until it encounters its first await expression (details). Then it returns a Future object, resuming execution only after the await expression completes.

//Future instance it's aka operation instance, with returned type. 
//and function body it's aka execution code of operation itself
Future<String> reportUserRole() async {
  var username = await fetchRole();
  return 'User role: $username';
}

Future<String> reportLogins() async {
  var logins = await fetchLoginAmount();
  return 'Total number of logins: $logins';
}
final myFuture = http.get('some_url');
myFuture.then((resp) {
    //it's a callback when future is done
});

Other experiments

 //Создается два отдельных исполняющих кода
  //если вызов метода делать с задержкой в 3 секунды со значениями 1 , 2
  //то через 5 секуд выведется value: 1 d: 2,
  // и еще через 3 (т.е. через 5 после второго вызова)  value: 2 d: 2

  int d = 0;

  void checkAsync(int value) async {
    d = value;
    int v = value;
    await Future.delayed(Duration(seconds: 5));

    _log('value: $v d: $d');
  }

Clone this wiki locally