我正在努力理解,飞镖事件循环是如何工作的。我阅读了事件循环与省道网站的事件循环文章,作者很好地解释了dart中事件循环是如何工作的。
但我不明白的是,事件是如何排队的。例如
new Future(() => 21)
.then((v) => v*2)
.then((v) => print(v));这里的飞镖会在事件队列中创建三个条目还是一个条目?我知道,类未来负责延迟执行,当我从它创建一个对象时,比如
new Future(() => 21)它将只是事件循环中的一个条目。
在我上面提到的这篇文章中,我读到了有关microtask的文章。这个微任务将在事件队列之前执行,但我看不出有什么意义,为什么省道小组会执行这个微任务?也许我需要一些例子!
发布于 2014-06-04 10:50:54
经过一些调查后,似乎正确的答案是“它们将在下一个事件循环中执行”。
要测试它,您可以编写如下内容:
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):
使用这样的代码:
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");
});
}产出如下:
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
...但有了这个:
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 事件循环
而不是按照时间表的顺序。
发布于 2014-06-04 18:56:41
当你这样做时:
new Future(() => 21)
.then((v) => v*2)
.then(print);new Future(...)构造函数。这将创建一个未来对象,并安排一个计时器来执行作为参数提供的函数。then。这将创建一个新的未来(称为future#2),并在第一个未来添加一个侦听器。没有安排任何活动。then。这将创建另一个未来(future#3),并在future#2上添加一个侦听器。没有计划事件。()=>21,第一个未来以值21完成。(v)=>v*2,然后用值42完成future#2。print,后者打印42并返回null。这使用值future#3完成了null。未来的完成目前是通过一个“传播”函数来完成的,该函数试图尽可能多地完成未来,只要它们的侦听器是同步的。这就是为什么完成一个未来将立即完成另一个,而不需要任何中间的微任务。
发布于 2014-06-04 06:22:37
微任务队列用于队列异步执行,但避免在这些微任务完成之前返回到主事件循环。在执行主队列中排队的其他异步任务/事件之前,即使在执行异步时,您也可以确保完全完成一些相关的活动。
从then执行的代码(如(v) => v*2 )似乎再次在Future中执行,因为then总是返回Future。
来自https://www.dartlang.org/articles/event-loop/
微任务队列是必要的,因为事件处理代码有时需要稍后完成任务,但在将控制返回到事件循环之前。例如,当一个可观察到的对象发生变化时,它会将多个突变组合在一起,并以不定期的方式报告它们。microtask队列允许可观察对象在DOM显示不一致状态之前报告这些突变变化。
我对这个描述的解释与@Jare的答案中的测试结果不符。
https://stackoverflow.com/questions/24030271
复制相似问题