二、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()来处理异常。

相关文章
相关标签/搜索