異步 Stream

flutter 異步方式
  • Future
  • Completer
  • Async/await
  • Stream

Completer

Completer 控制 Future 和async await一樣

  Future<void> testAsync()  {
      Completer comp = Completer();
      Future.delayed(Duration(seconds: 2),(){
        print("2");
        comp.complete();
      });
      print("1");
      return comp.future;
  }

  testAsync().then((value){
      print("3");
  });

執行結果 1,2,3

Stream

stream 是一個事件流的,當狀態變化,就會通知監聽回調; 對于UI上的 StreamBuilder一般比較好的是 可以通過異步繪制,當stream流數據變化,會自動重新繪制UI

對 stream 改為同步,使用await無效,

因為只能通過監聽異步回調才能得到結果
所以需要先通過stream 監聽保存數據,
再使用 延遲 sleep 等待幾秒再去重新查詢狀態

// ZSBlue.instance.state 是 stream流
if (ZSBlue.instance.state == null) {
      // 還未設置 初始化 延遲一會
      await Future.delayed(Duration(milliseconds: 10));
}

if (ZSBlue.instance.state == BluetoothState.unauthorized ) {
     //前往設置授權", "“發得快”連接打印設備");
     return false;
};
if (ZSBlue.instance.state == null) {
    // 等待結束還未初始化完
    // 提示 “藍牙異常 請稍后重試”
     return false;
}

Timer 和 Future.delayed 區別

兩個都可以時間延遲 執行部分

Future.delayed 可能會報錯
如果在延遲結束的時候 函數已經 return 掉

Timer 可以取消,因此盡量使用 Timer來延遲執行

/*
* 這是一個 主動輪詢查詢 狀態的, 在超時后結束輪詢 
* 超時認為狀態獲取失敗
*/
static Future<ZSBluePrinterState> readStatues() async {
    bool endFun = false;

    // 如果使用Future.delayed 輪訓提前結束,延遲后面到時間后會報錯
    // 因為當前函數已經 return了
    // Future.delayed(Duration(milliseconds: 500),(){
    Timer t = Timer(Duration(milliseconds: 500), () {
      if (endFun == false) {
        print(" ----------- 讀取狀態 超時了 -------- ");
        setStateByBytes([]);
      }
    });

    while (zsPrinteStateReading == true) {
      await Future.delayed(Duration(milliseconds: 1));
    }

    t.cancel();
    endFun = true;
    return printerState;
  }

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容