首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Dart事件队列和微任务

Dart事件队列和微任务
EN

Stack Overflow用户
提问于 2014-06-04 06:13:11
回答 4查看 6K关注 0票数 9

我正在努力理解,飞镖事件循环是如何工作的。我阅读了事件循环与省道网站的事件循环文章,作者很好地解释了dart中事件循环是如何工作的。

但我不明白的是,事件是如何排队的。例如

代码语言:javascript
复制
new Future(() => 21)
    .then((v) => v*2)
    .then((v) => print(v));

这里的飞镖会在事件队列中创建三个条目还是一个条目?我知道,类未来负责延迟执行,当我从它创建一个对象时,比如

代码语言:javascript
复制
new Future(() => 21)

它将只是事件循环中的一个条目。

在我上面提到的这篇文章中,我读到了有关microtask的文章。这个微任务将在事件队列之前执行,但我看不出有什么意义,为什么省道小组会执行这个微任务?也许我需要一些例子!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-06-04 10:50:54

经过一些调查后,似乎正确的答案是“它们将在下一个事件循环中执行”。

要测试它,您可以编写如下内容:

代码语言:javascript
复制
import "dart:async";
void main() {
  new Future(() {
    scheduleMicrotask(()=>print("before loop 1"));
    print("in event loop");
  }).then((_) {
    scheduleMicrotask(()=>print("before loop 2"));
    print("in event loop");
  }).then((_) {
    scheduleMicrotask(()=>print("before loop 3"));
    print("in event loop");
  });
}

它应产出:

事件循环 事件循环 事件循环 前循环1 前循环2 前循环3

虽然我不确定你不能破坏这个优化。因此,唯一确定的事实是,第一个Future将完成第一个和第二个.

编辑:奇怪的part(Obsolete):

使用这样的代码:

代码语言:javascript
复制
import "dart:async";
void main() {
  new Future(() {
    scheduleMicrotask(print("before loop 1"));
    print("in event loop");
  }).then((_) {
    scheduleMicrotask(print("before loop 2"));
    print("in event loop");
  }).then((_) {
    scheduleMicrotask(print("before loop 3"));
    print("in event loop");
  });
}

产出如下:

代码语言:javascript
复制
before loop 1
in event loop
before loop 2
in event loop
before loop 3
in event loop
Unhandled exception:
The null object does not have a method 'call'.

NoSuchMethodError: method not found: 'call'
Receiver: null
...

但有了这个:

代码语言:javascript
复制
import "dart:async";
void main() {
  new Future(() {
    scheduleMicrotask(()=>print("before loop 1"));
    print("in event loop");
  }).then((_) {
    scheduleMicrotask(()=>print("before loop 2"));
    print("in event loop");
  }).then((_) {
    scheduleMicrotask(()=>print("before loop 3"));
    print("in event loop");
  });
}

产出如下:

事件循环 事件循环 事件循环 前循环1 前循环2 前循环3

EDIT2:

我想我明白了。在第一个版本(错误的版本)中,scheduleMicrotask实际上从来没有得到正确的调度,但是由于Dart有急切的参数执行,所以它无论如何都会执行print()。因此,在下一个事件循环中执行所有Future并打印所有文本。这就是输出按调用顺序排列的原因:

前循环1 事件循环 前循环2 事件循环 前循环3 事件循环

而不是按照时间表的顺序。

票数 6
EN

Stack Overflow用户

发布于 2014-06-04 18:56:41

当你这样做时:

代码语言:javascript
复制
new Future(() => 21)
.then((v) => v*2)
.then(print);
  • 首先,调用new Future(...)构造函数。这将创建一个未来对象,并安排一个计时器来执行作为参数提供的函数。
  • 然后打电话给then。这将创建一个新的未来(称为future#2),并在第一个未来添加一个侦听器。没有安排任何活动。
  • 然后你再打电话给then。这将创建另一个未来(future#3),并在future#2上添加一个侦听器。没有计划事件。
  • 然后计时器触发,执行()=>21,第一个未来以值21完成。
  • 然后立即执行第一个未来的侦听器。它用21调用(v)=>v*2,然后用值42完成future#2。
  • 然后立即执行future#2上的侦听器。它用42调用print,后者打印42并返回null。这使用值future#3完成了null

未来的完成目前是通过一个“传播”函数来完成的,该函数试图尽可能多地完成未来,只要它们的侦听器是同步的。这就是为什么完成一个未来将立即完成另一个,而不需要任何中间的微任务。

票数 6
EN

Stack Overflow用户

发布于 2014-06-04 06:22:37

微任务队列用于队列异步执行,但避免在这些微任务完成之前返回到主事件循环。在执行主队列中排队的其他异步任务/事件之前,即使在执行异步时,您也可以确保完全完成一些相关的活动。

then执行的代码(如(v) => v*2 )似乎再次在Future中执行,因为then总是返回Future

来自https://www.dartlang.org/articles/event-loop/

微任务队列是必要的,因为事件处理代码有时需要稍后完成任务,但在将控制返回到事件循环之前。例如,当一个可观察到的对象发生变化时,它会将多个突变组合在一起,并以不定期的方式报告它们。microtask队列允许可观察对象在DOM显示不一致状态之前报告这些突变变化。

我对这个描述的解释与@Jare的答案中的测试结果不符。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24030271

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档