Future常用的異步函數(shù)

Future常用的異步函數(shù)

Future是一種表示可能異步返回值的對象。當我們需要執(zhí)行一個可能會阻塞主線程的操作時,可以使用Future來使這個操作異步執(zhí)行,這樣就不會阻塞UI線程。

一、 異步函數(shù)

Future:

Future是一種表示可能會返回結果的未來值的對象??梢允褂胊sync和await關鍵字來處理Future。

Future fetchData() async {
  // 模擬耗時操作
  await Future.delayed(Duration(seconds: 2));
  return 'Data fetched successfully!';
}

void main() async {
  print('Fetching data...');
  String data = await fetchData();
  print(data);
}

async和await:

async關鍵字用于修飾函數(shù),表示該函數(shù)是一個異步函數(shù),可以在其中使用await關鍵字來等待異步操作的結果。

Future fetchData() async {
  // 模擬耗時操作
  await Future.delayed(Duration(seconds: 2));
  return 'Data fetched successfully!';
}

void main() async {
  print('Fetching data...');
  String data = await fetchData();
  print(data);
}

Future.delayed:

可以使用Future.delayed創(chuàng)建一個延遲一段時間后返回結果的Future。

void main() async {
  print('Start');
  await Future.delayed(Duration(seconds: 2), () {
    print('Delayed action');
  });
  print('End');
}

Future.wait:

如果需要同時等待多個異步操作完成,可以使用Future.wait。

Future fetchUser() {
  return Future.delayed(Duration(seconds: 2), () => 'User fetched');
}

Future fetchPosts() {
  return Future.delayed(Duration(seconds: 3), () => 'Posts fetched');
}

void main() async {
  print('Fetching data...');
  List> futures = [fetchUser(), fetchPosts()];
  List results = await Future.wait(futures);
  print(results);
}

Future.value:

是Flutter中的一個靜態(tài)方法,用于創(chuàng)建一個已經(jīng)完成(已解析)的Future對象,該對象的結果值為指定的值。

Future.value()方法的作用是立即返回一個已經(jīng)完成的Future對象,且該Future對象的結果值就是指定的value值。這意味著可以通過該Future對象進行異步操作的編程模型,如使用await關鍵字等。

void main() async {
  Future future = Future.value(42);
  int result = await future;
  print(result); // 輸出: 42
}

在上述示例中,F(xiàn)uture.value(42)會創(chuàng)建一個已經(jīng)完成的Future對象,結果值為42。通過await關鍵字,可以等待該Future對象的結果,然后將結果賦值給result變量,并打印出結果值42。

Future.value()方法在某些情況下非常有用,例如將同步的結果值轉換為Future對象,或者作為其他異步操作的初始值。它提供了一種簡便的方式來創(chuàng)建并返回一個已經(jīng)完成的Future對象。

Future.doWhile:

Future.doWhile 是 Future 類的一個實例方法,用于執(zhí)行一個異步操作的循環(huán),直到指定的條件不再滿足為止。

Future doWhile(FutureOr Function() action)

參數(shù) action 是一個回調函數(shù),它將被反復調用執(zhí)行,直到返回的結果為 false?;卣{函數(shù) action 可以是一個 Future 類型的函數(shù),也可以是一個同步函數(shù)。

使用 Future.doWhile 方法可以實現(xiàn)異步的循環(huán)操作,以處理某些需要重復執(zhí)行的異步任務,直到條件不再滿足為止。

void main() async {
  int count = 0;
  
  await Future.doWhile(() async {
    await Future.delayed(Duration(seconds: 1));
    count++;
    print(count);
    
    return count < 5;
  });
  
  print('Loop completed');
}

Future.forEach:

Future.forEach 是 Future 類的一個實例方法,用于對一個集合進行異步迭代操作,并對集合中的每個元素執(zhí)行指定的異步操作。

Future forEach(void Function(T element) action)

參數(shù) action 是一個回調函數(shù),它將被異步調用以處理集合中的每個元素。回調函數(shù) action 接受一個參數(shù) element,表示集合中的當前元素。

使用 Future.forEach 方法可以方便地對集合進行異步迭代操作,處理集合中的每個元素的異步任務,等待所有的任務完成后返回一個 Future 對象。

void main() async {
  List numbers = [1, 2, 3, 4, 5];
  
  await Future.forEach(numbers, (int number) async {
    await Future.delayed(Duration(seconds: 1));
    print(number);
  });
  
  print('Iteration completed');
}

Future.microtask:

Future.microtask 是 Future 類的一個靜態(tài)方法,用于將一個微任務(microtask)添加到事件循環(huán)中,在當前事件循環(huán)的微任務隊列中立即執(zhí)行。

微任務是指一種高優(yōu)先級的任務,它會在事件循環(huán)的任務隊列中的其他任務之前執(zhí)行。使用 Future.microtask 方法可以將一個回調函數(shù)添加到當前微任務隊列中,以便在當前事件循環(huán)中的其他任務執(zhí)行完成后立即執(zhí)行。

static Future microtask(FutureOr computation())

參數(shù) computation 是一個回調函數(shù),它將被添加到當前微任務隊列中執(zhí)行?;卣{函數(shù) computation 可以是一個 Future 類型的函數(shù),也可以是一個同步函數(shù)。

使用 Future.microtask 方法可以在當前事件循環(huán)的微任務隊列中執(zhí)行一些高優(yōu)先級的任務,而不會延遲其他任務的執(zhí)行。

void main() {
  print('Start');
  
  Future.microtask(() {
    print('Inside microtask');
  });
  
  print('End');
}

在上述示例中,我們在 main 函數(shù)中使用 Future.microtask 方法添加了一個微任務。該微任務會在當前事件循環(huán)的任務隊列中的其他任務執(zhí)行完成后立即執(zhí)行。因此,在打印 "Start" 和 "End" 之間,微任務中的回調函數(shù)會被執(zhí)行,打印出 "Inside microtask"。

需要注意的是,F(xiàn)uture.microtask 方法的回調函數(shù)在當前事件循環(huán)中的微任務隊列中執(zhí)行,因此不會創(chuàng)建新的事件循環(huán),也不會引發(fā)事件循環(huán)的重新調度。這使得微任務的執(zhí)行速度非???,適用于需要立即執(zhí)行的高優(yōu)先級任務,例如狀態(tài)更新、回調通知等。

另外,需要注意避免濫用 Future.microtask 方法,以免阻塞事件循環(huán)的正常執(zhí)行。只有在必要的情況下,才應該使用微任務。

Future.sync:

Future.sync 是 Future 類的一個靜態(tài)方法,用于創(chuàng)建一個同步執(zhí)行的 Future 對象。

static Future sync(T computation())

參數(shù) computation 是一個回調函數(shù),它將在當前執(zhí)行上下文中同步執(zhí)行?;卣{函數(shù) computation 可以是一個任意類型的函數(shù),返回值類型為 T。

使用 Future.sync 方法可以將同步的計算操作封裝為一個 Future 對象,以便與異步操作進行一致的編程模型。

void main() {
  Future future = Future.sync(() {
    return 42;
  });
  
  future.then((value) {
    print(value); // 輸出: 42
  });
  
  print('End');
}

在上述示例中,我們使用 Future.sync 方法創(chuàng)建了一個同步的 Future 對象。回調函數(shù)中的計算操作直接返回了一個整數(shù)值 42。通過 future.then 方法,我們可以注冊一個回調函數(shù),當 Future 對象完成時將被調用。在回調函數(shù)中,我們打印出了 Future 對象的結果值 42。

需要注意的是,盡管 Future.sync 方法的回調函數(shù)是同步執(zhí)行的,但返回的 Future 對象仍然具有異步的特性,因為它是 Future 類的實例。因此,可以在返回的 Future 對象上使用異步的方法和操作,例如 then、catchError 等。

另外,由于 Future.sync 方法的回調函數(shù)是在當前執(zhí)行上下文中同步執(zhí)行的,所以在回調函數(shù)中避免進行長時間的阻塞操作,以免影響整個應用程序的響應性。

二、 異步組件

在Flutter中,有一些用于處理異步操作的常用組件。這些組件可用于優(yōu)化用戶界面,顯示加載狀態(tài),處理錯誤等。以下是一些常用的異步組件:

1、 FutureBuilder:

用于根據(jù) Future 的不同狀態(tài)構建界面。它接收一個 Future 對象,并根據(jù)異步操作的狀態(tài)(未完成、完成、出錯)來構建相應的UI。

Future fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  return 'Data fetched successfully';
}

Widget build(BuildContext context) {
  return FutureBuilder(
    future: fetchData(),
    builder: (BuildContext context, AsyncSnapshot snapshot) {
      if (snapshot.connectionState == ConnectionState.waiting) {
        return CircularProgressIndicator();
      } else if (snapshot.hasError) {
        return Text('Error: ${snapshot.error}');
      } else {
        return Text('Data: ${snapshot.data}');
      }
    },
  );
}

2、 StreamBuilder:

用于監(jiān)聽 Stream 的事件并構建相應的UI。它接收一個 Stream 對象,并根據(jù)數(shù)據(jù)流的事件(數(shù)據(jù)、錯誤、完成)來構建界面。

Stream countStream() async* {
  for (int i = 1; i <= 5; i++) {
    await Future.delayed(Duration(seconds: 1));
    yield i;
  }
}

Widget build(BuildContext context) {
  return StreamBuilder(
    stream: countStream(),
    initialData: 0,
    builder: (BuildContext context, AsyncSnapshot snapshot) {
      if (snapshot.connectionState == ConnectionState.waiting) {
        return CircularProgressIndicator();
      } else if (snapshot.hasError) {
        return Text('Error: ${snapshot.error}');
      } else {
        return Text('Count: ${snapshot.data}');
      }
    },
  );
}

3、 RefreshIndicator:

提供了下拉刷新的功能,用于更新顯示的數(shù)據(jù)。它通常與一個 ListViewGridView 組件結合使用。

List<String> dataList = ['Item 1', 'Item 2', 'Item 3'];

Future<void> refreshData() async {
  await Future.delayed(Duration(seconds: 2));
  setState(() {
    dataList = ['Updated Item 1', 'Updated Item 2', 'Updated Item 3'];
  });
}

Widget build(BuildContext context) {
  return RefreshIndicator(
    onRefresh: refreshData,
    child: ListView.builder(
      itemCount: dataList.length,
      itemBuilder: (BuildContext context, int index) {
        return ListTile(
          title: Text(dataList[index]),
        );
      },
    ),
  );
}

4、 StreamBuilderFutureBuilder 的衍生組件:

Flutter社區(qū)提供了許多基于 StreamBuilderFutureBuilder 的衍生組件,用于處理更特定的異步場景,例如:

  • BlocBuilder:與狀態(tài)管理庫(如BLoC、Provider、Riverpod等)結合使用,用于構建基于數(shù)據(jù)流的界面。

  • ValueListenableBuilder:用于監(jiān)聽 ValueListenable 對象的變化并構建相應的界面。

  • `Animated

Builder:根據(jù)動畫的值來構建界面,通常與 AnimationController` 和其他動畫類一起使用。

三、 Flutter處理異步操作的結果和錯誤

在Flutter中,Future 類提供了許多方法來處理異步操作的結果和錯誤。以下是這些方法的說明:

1、 then:

注冊一個回調函數(shù),該函數(shù)會在異步操作成功完成時被調用,并接收異步操作的結果作為參數(shù)。

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  return 'Data fetched successfully';
}

fetchData().then((data) {
  print(data);
});

2、 catchErroronError:

注冊一個回調函數(shù),該函數(shù)會在異步操作發(fā)生錯誤時被調用,并接收錯誤信息作為參數(shù)。

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  throw Exception('Error occurred');
}

fetchData().catchError((error) {
  print('Error: $error');
});

3、 error:

獲取異步操作的錯誤信息,如果異步操作發(fā)生錯誤的話。

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  throw Exception('Error occurred');
}

fetchData().then((data) {
  print(data);
}).catchError((error) {
  print('Error: ${error.toString()}');
});

4、 whenComplete:

注冊一個回調函數(shù),在異步操作完成時(不管成功或失?。┍徽{用,不接收任何參數(shù)。

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  return 'Data fetched successfully';
}

fetchData().then((data) {
  print(data);
}).catchError((error) {
  print('Error: $error');
}).whenComplete(() {
  print('Async operation completed');
});

5、 timeout:

設置異步操作的超時時間,并返回一個新的 Future,如果超時則會觸發(fā)錯誤。

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 5));
  return 'Data fetched successfully';
}

fetchData().timeout(Duration(seconds: 3), onTimeout: () {
  throw TimeoutException('Operation timed out');
}).then((data) {
  print(data);
}).catchError((error) {
  print('Error: $error');
});

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容