1. 程式人生 > >dart 非同步事件執行流程分析(二)

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高效的多。

 
吐槽,為什麼每次程式碼粘貼後格式都亂了啊,還得重新格式化。