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]
Exited

 

因此对于大型多次的异步IO操作来说,恰当的使用then要比await高效的多。

 


吐槽,为什么每次代码粘贴后格式都乱了啊,还得重新格式化。

给TA打赏
共{{data.count}}人
人已打赏
安全技术

c++ list, vector, map, set 区别与用法比较

2022-1-11 12:36:11

安全漏洞

预警runc 符号链接挂载与容器逃逸漏洞(CVE-2021-30465)

2021-7-11 11:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索