Dart庫中有大量返回結果為Future或Stream類型的函數,它們都是非同步函數,函數的返回結果在構建可能存在耗時操作之後就返回了(如:網路IO操作),而不是同步等到這些耗時操作完成後在返回。關鍵字async和wait簡化了非同步編程(如:回調地獄),讓非同步代碼的編寫看起來像同步代碼一樣…… ...
Dart官方文檔:https://dart.dev/language/async
重要說明:本博客基於Dart官網文檔,但並不是簡單的對官網進行翻譯,在覆蓋核心功能情況下,我會根據個人研發經驗,加入自己的一些擴展問題和場景驗證。
Future處理
我們有2種方式編寫Future非同步代碼:
- 使用
async
和wait
關鍵字 - 使用Future API(https://dart.dev/guides/libraries/library-tour#future)
推薦使用async
和wait
關鍵字,讓非同步代碼看起來和同步代碼一樣。
如下代碼樣例:wait
關鍵字等待非同步函數返回結果,它必須在async
函數中。
Future<void> checkVersion() async {
var version = await lookUpVersion();
var exitCode = await findExitCode();
// ......
await flushThenExit(exitCode);
}
可以用try
、catch
和finally
關鍵字處理錯誤和清理代碼:
try {
version = await lookUpVersion();
} catch (e) {
// React to inability to look up the version
} finally {
// Clean code
}
申明非同步函數
使用async
修飾一個函數體,這個函數就是非同步函數,它的返回結果是一個Future<T>
,當函數無需返回結果時,返回結果為Future<void>
:
Future<String> lookUpVersion async {
// ......
return '1.0.1';
}
Future<void> doSomething() {
// ......
}
Stream處理
同樣的,我們也有2種方式編寫Stream代碼:
- 在非同步迴圈使用
async
非同步關鍵字(await for
) - 使用Stream API(https://dart.dev/guides/libraries/library-tour#stream)
推薦使用async
關鍵字,非同步迴圈的形式如下:
await for (varOrType identifier in expression) {
// ......
}
在上訴非同步迴圈形式中,expression
的值為一個Stream類型,非同步迴圈的執行過程如下:
- 等待Stream產出一個值(即觸發迴圈執行)
- 設置identifier變數值,執行迴圈體邏輯
- 重覆上面2步,直到Stream關閉(即迴圈結束)
我們可以通過break
或者return
語句,退出迴圈,從而中斷監聽Stream生產的值。
同樣的,非同步迴圈的函數,必須使用async
關鍵字修飾。如下所示,main()
函數體使用了await for
非同步迴圈,則函數必須使用async
修飾:
void main() async {
// ......
await for (final request in requestServer) {
handleRequest(request);
}
// ......
}
最後
- 第4課對非同步編程文檔(Future和async/await):https://ntopic.cn/p/2023092901
- 其他更多關於非同步編程信息,請求參考非同步包
dart:async
(https://dart.dev/guides/libraries/library-tour#dartasync---asynchronous-programming)
我的本博客原地址:https://ntopic.cn/p/2023111801
本文作者:奔跑的蝸牛,轉載請註明原文鏈接:https://ntopic.cn