Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event Queues and Microtask Queues

Tags:

flutter

dart

In the Dart documentation The Event Loop and Dart (2013) it mentions that any Future is added to the Event queue.

It also mentions that Microtask queues are meant to always run first, then Event queues.

This documentation is old, and seems geared towards web development so I'm not sure if this is different for Flutter as when I do this code.

Future<String> myFunction() => new Future.value('Hello');
Future<String> myFunction2() => new Future.value('Hello2');
Future<void> mainTest() async {
  debugPrint("Sync1");  
  myFunction().then(debugPrint);
  scheduleMicrotask(() { debugPrint("Microtask"); });
  myFunction2().then(debugPrint);  
  debugPrint("Sync2");
}

I get an output of

I/flutter ( 6731): Sync1
I/flutter ( 6731): Sync2
I/flutter ( 6731): Hello
I/flutter ( 6731): Microtask
I/flutter ( 6731): Hello2

But if all Microtasks were meant to be run before the next Event loop, shouldn't it be this?

I/flutter ( 6731): Sync1
I/flutter ( 6731): Sync2
I/flutter ( 6731): Microtask // This running first before the Futures?
I/flutter ( 6731): Hello
I/flutter ( 6731): Hello2
like image 351
Adam Avatar asked Jan 14 '19 11:01

Adam


2 Answers

This would be the case if you were invoking methods without calling .then

A way to add a task to the microtask queue is to invoke then() on a Future that’s already complete.

So when you call myFunction().then(print); future is added to microtask queue.

Some bonus facts for the cases when calling without '.then': According to the docs there were 2 bugs. These bugs were fixed, but the issue still remains :(

The upshot of these bugs: The first task that you schedule with scheduleMicrotask() seems like it’s on the event queue.

A workaround is to put your first call to scheduleMicrotask() before your first call to new Future()

like image 125
Nuts Avatar answered Oct 10 '22 03:10

Nuts


Notes for the general reader:

  • The Event Loop has two queues of tasks: the Microtask Queue and the Event Queue.
  • Any tasks in the Microtask Queue are always run before the next task in the Event Queue.
  • Microtasks are generally scheduled by the system while Event Queue tasks generally come from the outside events (IO, app events, etc.).

I believe the following points explain the behavior that you are observing:

  • The Future.value() constructor schedules a microtask on the Microtask Queue.

  • The Future() constructor, on the other hand, schedules a regular task on the Event Queue.

The original link you shared is only available as an archive now:

  • The Event Loop and Dart

It is still worth reading, though.

like image 44
Suragch Avatar answered Oct 10 '22 05:10

Suragch