前言 在開發過程中,取消需求是很常見的,但很容易被忽略。然而,取消需求的好處也很大。例如,在頁面中會發送很多請求。如果頁面被切走並處於不可見狀態,就需要取消未完成的請求任務。如果未及時取消,則可能會導致以下負面影響: 消耗用戶額外數據流量。 任務回調持有全局上下文變數,未及時釋放存在記憶體泄漏風險 異 ...
前言
在開發過程中,取消需求是很常見的,但很容易被忽略。然而,取消需求的好處也很大。例如,在頁面中會發送很多請求。如果頁面被切走並處於不可見狀態,就需要取消未完成的請求任務。如果未及時取消,則可能會導致以下負面影響:
- 消耗用戶額外數據流量。
- 任務回調持有全局上下文變數,未及時釋放存在記憶體泄漏風險
- 非同步請求過多消耗大量系統資源,拖慢 UI 線程,造成卡頓。
在 Flutter 中,如何取消已經在進行的任務呢?首先需要掌握一些基礎知識。
前置知識
Future#any 方法
傳入一個 Future 任務列表,返回第一個完成的非同步任務,無論成功或失敗。
定義
用法
如下 5 個非同步任務,代碼第五行雖然第二執行,但是最先執行完畢,所以第一個返回,至此整個 Future.any 函數執行完畢。
結果輸入如下:
總結
- Future.any 實際就是一個 Completer,N 個 Future 疊加在一起,誰先完成算誰的。
- Future.any 可以理解成百米賽跑,其中每個選手就是一個 Future,誰跑最快到終點誰就贏了。
Dio 取消實現解析
dio 版本
dio: dev v5.0.3
git: 67f07b86a0976c14a6e19061563832d92ed6772b
branch: main
如何取消
請求中傳入 CancelToken 對象,然後調用 token.cancel 方法即可
final cancelToken = CancelToken();
dio.get(url, cancelToken: cancelToken).catchError((DioError err) {
if (CancelToken.isCancel(err)) {
print('Request canceled: ${err.message}');
} else{
// handle error.
}
});
// Cancel the requests with "cancelled" message.
token.cancel('cancelled');
流程解析
思路:在實際任務執行前使用 Future.any 函數插入取消任務。如果實際任務沒有執行完,就有機會取消它。
如下代碼,黃色標註按照步驟來讀就行。
總結:CancelToken 就像一個渣男,而 Future.any 則提供了公平競爭的機會。只要妹子還沒有交男朋友,渣男就有機會中途得手。
說明
取消任務不僅限於網路請求。任何實際業務中包含不必要的耗時操作都可以通過 Future.any 配合 CancelToken 來實現取消。