二、Dart:異步編程之Futures;

  Dart代碼在一個執行的'線程'中運行。Future對象表明異步操做的結果:稍後要完成的處理或I/O。要暫停執行直到未來完成,要在異步函數中使用await(或使用then())。要捕獲錯誤,要在異步函數中使用try-catch表達式(或使用catchError())。要同時運行代碼,請建立isolateapi

Futures

  future是Future<T>對象,表示產生類型T結果的異步操做。若是沒有返回結果,則future的類型爲Future <void>,當調用返回future的函數時,會發生兩件事:異步

  1. 該函數將要完成的工做排隊並返回未完成的Future對象。
  2. 稍後,當操做完成時,Future對象將以值或錯誤完成。

  編寫依賴於將來的代碼時,您有兩種選擇:async

  • 使用asyncawait
  • 使用Futureapi。

async和await

  asyncawait關鍵字是Dart語言異步支持的一部分。 它們容許編寫看起來像同步代碼的異步代碼,而不使用Future API。 異步函數是在其正文以前具備async關鍵字的函數。 await關鍵字僅適用於異步函數。函數

注意:在Dart 1.x中,異步函數當即暫停執行。 在Dart 2中,異步函數不是當即掛起,而是同步執行,直到第一個等待或返回。ui

import 'dart:async';

Future<void> printDailyNewsDigest() async {
  var newsDigest = await gatherNewsReports();
  print(newsDigest);
}
main() {
  printDailyNewsDigest();
  printWinningLotteryNumbers();
  printWeatherForecast();
  printBaseballScore();
}

printWinningLotteryNumbers() {
  print('Winning lotto numbers: [23, 63, 87, 26, 2]');
}

printWeatherForecast() {
  print("Tomorrow's forecast: 70F, sunny.");
}

printBaseballScore() {
  print('Baseball score: Red Sox 10, Yankees 0');
}

const news = '<gathered news goes here>';
const oneSecond = Duration(seconds: 1);

Future<String> gatherNewsReports() =>
    Future.delayed(oneSecond, () => news);
複製代碼
處理錯誤

  若是Future-returns函數因錯誤而完成,您可能但願捕獲該錯誤。 異步函數可使用try-catch處理錯誤:spa

Future<void> printDailyNewsDigest() async {
  try {
    var newsDigest = await gatherNewsReports();
    print(newsDigest);
  } catch (e) {
    // Handle error...
  }
}
複製代碼
順序處理

  可使用多個await表達式來確保每一個語句在執行下一個語句以前完成:線程

main() async {
  await expensiveA();
  await expensiveB();
  doSomethingWith(await expensiveC());
}
複製代碼

expensiveA()完成以前,expensiveB()函數不會執行,依此類推。code

Future API

  在Dart 1.9中添加asyncawait以前,必須使用Future API。 您可能仍會看到舊代碼中使用的Future API以及須要比async-await提供的功能更多的代碼。對象

  要使用Future API編寫異步代碼,可使用then()方法註冊回調。 當Future完成時,此回調將觸發。同步

import 'dart:async';

Future<void> printDailyNewsDigest() {
  final future = gatherNewsReports();
  return future.then(print);
}

main() {
  printDailyNewsDigest();
  printWinningLotteryNumbers();
  printWeatherForecast();
  printBaseballScore();
}

printWinningLotteryNumbers() {
  print('Winning lotto numbers: [23, 63, 87, 26, 2]');
}

printWeatherForecast() {
  print("Tomorrow's forecast: 70F, sunny.");
}

printBaseballScore() {
  print('Baseball score: Red Sox 10, Yankees 0');
}

const news = '<gathered news goes here>';
const oneSecond = Duration(seconds: 1);


Future<String> gatherNewsReports() =>
    Future.delayed(oneSecond, () => news);
複製代碼

  須要爲then()的回調提供一個參數,即便Future的類型爲Future 。 按照慣例,未使用的參數名爲_(下劃線)。

final future = printDailyNewsDigest();
return future.then((_) {
  print('All reports printed.');
});
複製代碼
處理錯誤

  使用Future API,您可使用catchError()捕獲錯誤:

Future<void> printDailyNewsDigest() =>
    gatherNewsReports().then(print).catchError(handleError);
複製代碼
使用Future.wait()完成多個Future

  若是函數的執行順序不重要,可使用Future.wait()。當傳遞Future.wait()一個Futures List時,它會當即返回一個Future。 在全部給定的Futures完成以前,Future不會完成。 而後它以一個List完成,該List包含原始列表中每一個future的值。

Future.wait([expensiveA(), expensiveB(), expensiveC()])
    .then((List responses) => chooseBestResponse(responses, moreInfo))
    .catchError(handleError);
複製代碼

  若是任何調用的函數因異常而完成,則Future.wait()返回的Future也會以異常完成。 使用catchError()來處理異常。

相關文章
相關標籤/搜索