Dart:无法理解异步/唤醒,未来和事件循环如何协同工作

问题描述

我是Dart的新手。我从一些文章和文档(例如this article)中了解到:

  1. async/await使用与Future相同的机制,即FIFO Event Loop
  2. Event Loop在执行main()之后启动。
  3. async函数同步运行 直到第一个await关键字。然后他们暂停执行,然后执行返回到调用堆栈中的上一个函数。
  4. 剩余的代码包装到Future并排队到Event Loop(对我来说最不确定的地方)。

基于这些观点,我期望以下代码:

main() {
  Future(() => print("1"));
  Future(() {
    print("2");
    asyncFunc("2");
  });
  Future(() => print("3"));

  print("main");
  asyncFunc("main");
  print("\nEvent loop starts?\n");
}

asyncFunc(String from) async {
  print("start  [from $from]");
  await (() async => print("middle [from $from]"))();
  print("end    [from $from]");
}

执行 main()后将创建与此事件队列类似的内容:
future1-> future2-> future3-> end_from_main
在执行future2之后,事件end_from_future2将被排到最后:
future1-> future2-> future3-> end_from_main-> end_from_future2

所以我期望的结果输出应该是:

main
start  [from main]
middle [from main]

Event loop starts?

1
2
start  [from 2]
middle [from 2]
3
end    [from main]
end    [from 2]

但实际上它返回:

main
start  [from main]
middle [from main]

Event loop starts?

end    [from main]
1
2
start  [from 2]
middle [from 2]
end    [from 2]
3

所以我得出的结论是:async/await个事件都比Fututre具有优先级。他们都使用与EventLoop无关的差异机制。也许我几乎误会了一些东西。

解决方法

我认为我了解的东西:

  • Future可以表示Event queue中的事件,也可以表示Microtask queue中的 tasks
    (例如:默认的Future()构造函数将 event 放入Event queueFuture.microtask() task 放入Microtask queue
  • await创建Future.than回调以获取Future

我的主题示例说明:

  • 前三个Futrue事件放入Event queue
  • Future<void>隐式创建
  • await (() async => print("asyncFunc middle"))()Microtask queue中创建“空” 任务(我假定所有隐式 Future被安排到Microtask queue)。比await将其余指令(print("end [from main]"))作为Future.than回调将此“空” 任务
  • 放置。
  • 涉及Event Loop时,它首先从Microtask queue执行“空” 任务。结束于回调:print("end [from main]")
  • 然后Event loop执行Event queue,第二个 event Microtask queue中产生类似的“空” 任务。这就是end [from 2]发生在第三Future之前的原因

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...