dart 异步事件执行流程分析(二)

// use two list to test the async envet exe order.
// one record the emitted order;
// and the other record the captured order;
import 'dart:math';

 

final rnd = Random();
final seed = 10;
final emitted = <int>[];
final captured = <int>[];

 

main() {
capture();
Future.delayed(Duration(seconds: 50), () { // to wait capture() over
print(isEqual(emitted, captured));
print(emitted);
print(captured);
});
}

 

void capture() async {
for (var i = 0; i < 5; i++) {
   // captured.add(await emit());
  emit().then((n) => captured.add(n));
  }
}

 

Future<int> emit() async {
var n = rnd.nextInt(seed);
emitted.add(n);
await Future.delayed(Duration(seconds: n));
return n;
}

 

bool isEqual(List<int> a, List<int> b) {
if (a.length != b.length) return false;
for (var i = 0; i < a.length; i++) {
  if (a[i] != b[i]) return false;
}
return true;
}

蓝色的两行代码:
   // captured.add(await emit());
  emit().then((n) => captured.add(n));
若是注释掉下面一行,执行上面一行,则两个list:emitted and captured的结果是一致的。await 起到了每一次emit的等待做用,代码顺序执行,但花费的总时间是串行的总时间之和,即O(Σ(n));
 
但若是把上面一行注释掉,执行下面一行,则两个list的结果就是不一样的。由于在下面一行then的回调中,通过测试发现,dart的异步 event loop不是顺序执行的。好比例子中5次emit(),根据生产的随机数delay,则随机delay时间最短的任务先完成,先调用在then()函数中注册的回调函数,所以captured中添加元素的顺序就和emit()发射的不一致,花费的时间是最大的delay的时间,即O(max(n))。output 以下:

false
[2, 6, 1, 7, 4]
[1, 2, 4, 6, 7]
Exiteddom

 

所以对于大型屡次的异步IO操做来讲,恰当的使用then要比await高效的多。异步

 

吐槽,为何每次代码粘贴后格式都乱了啊,还得从新格式化。
相关文章
相关标签/搜索