我想啟動一個 HttpRequest,然后輪詢它的完成情況。這感覺像是一個相當普遍的模式。
void main() {
_tick(0);
_tickB(0);
build();
print("End of main");
}
void build() {
var path = '../layout.txt';
html.HttpRequest.getString(path).then((String layout) {
print("layout received");
});
}
void _tick(int i) {
print("A $i");
if (i < 10) incr(i).then(_tick);
}
void _tickB(int i) {
print("B $i");
if (i < 10) incr(i).then(_tickB);
}
Future<int> incr(int i) async {
i ;
return i;
}
輸出:
A1
B1
End of main
A2
B2
A3
B3
A4
B4
A5
B5
layout received
我希望在 HttpRequest 完成時看到“收到的布局”與其他回呼交錯出現,但事實并非如此。它總是(無論 的值i,5 只是一個演示編號)在交錯回呼的末尾。
為什么是這樣?如何安排build回呼以使其在其他回呼鏈期間完成?
uj5u.com熱心網友回復:
您的incr函式實際上并沒有做任何異步作業。 incr將立即執行完成。由于回傳Future已經完成,它的Future.then回呼將被安排在微任務佇列中。只有在微任務佇列為空后,才會處理單獨的事件佇列。因此,您的_tick/_tickB函式通過重復將事件添加到微任務佇列并阻止您完成來創建(臨時)活鎖情況HttpRequest Future。
incr您可以通過做一些異步作業來獲得您期望的行為:
Future<int> incr(int i) async {
await Future.delayed(Duration.zero);
i ;
return i;
}
然后你的輸出將是:
A 0
B 0
End of main
A 1
B 1
layout received
A 2
B 2
A 3
B 3
...
進一步閱讀:事件回圈和 Dart
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/494480.html
