The dart documentation says that if the Future is completed, then the then methods will be run in one of the following microtasks. In the following example, everything works as expected because await is applied.
// print: exit_main, micro, then
main() async {
var p = Future.value(1);
await p;
scheduleMicrotask(() {
print('micro');
});
p.then((e) {
print('then');
});
print('exit_main');
}
But if await is removed, then the logic described above does not work. A microtask that is created before the then function is run after the then function is executed. But the then function is run after main, you can see that because a message is printed at the end of the main function.
// print: exit_main, then, micro
main() {
var p = Future.value(1);
scheduleMicrotask(() {
print('micro');
});
p.then((e) {
print('then');
});
print('exit_main');
}
In connection with what has been said, the following question. Why does the then function run before the created microtask?
Case 2 was expected to work just like the first case when await is applied.
CodePudding user response:
In the first case, the then method of the Future object is called within the context of an async function, and the await keyword is used to pause the execution of the function until the Future completes. This allows the microtask that was scheduled using scheduleMicrotask to be executed before the then method.
In the second case, the then method is called outside the context of an async function, so it is not paused by the await keyword. As a result, the then method is executed immediately after it is called, before the microtask that was scheduled using scheduleMicrotask.
Microtasks are tasks that are scheduled to be run after the current task is complete, but before the next "macrotask" is run. In the Dart runtime, microtasks are used to implement asynchronous programming patterns such as async/await. When an async function is paused using the await keyword, the runtime schedules a microtask to resume the function when the Future being awaited completes.
It's important to note that the order in which microtasks are executed is not guaranteed, and may vary depending on the runtime environment and the specific implementation of the scheduleMicrotask function. In general, however, microtasks are executed in the order in which they are scheduled.
CodePudding user response:
So, check these following cases:
In the first case, the await
keyword causes the program to pause execution until the Future
completes. This means that the then
callback and the microtask scheduled with scheduleMicrotask
are both run after the Future
has been completed.
In the second case, there is no await
keyword, so the program does not pause for the Future
to complete. Instead, the Future
is run asynchronously in the background, and the rest of the program continues to execute. This means that the then
callback and the microtask are both scheduled to run after the rest of the main function has been completed.
As you can see from the cases, the order in which microtasks are executed is determined by the JavaScript event loop. Microtasks are run in a separate queue from other tasks, and they are executed in the order in which they are added to the queue. In this case, the then
callback is added to the microtask queue before the microtask scheduled with scheduleMicrotask
, so the then
callback runs before the microtask.
CodePudding user response:
Understood, no answer needed. Presumably, the Future.value function with a simple value completes the Future in the future microtask, i.e. the Future is scheduled to complete before another microtask is called. After the Future completes, all then methods are called immediately, provided that they return a non-terminated Future. The behavior changes if the future has already completed. An example is presented below.
main() {
var p = Future.value(1);
Timer.run(() {
scheduleMicrotask(() {
print('micro');
});
p.then((e) {
print('then');
});
print('exit_main');
});
}