Dart 异步编程:futures,async,await

323 阅读1分钟

本篇文章我们将介绍在Dart中,如何使用futuresasyncawait关键字进行异步编码

为什么异步编码很重要

异步操作可以让我们的程序在完成一个任务之前,开始其他任务。在我们平时的开发中有以下常见的异步操作

  • 网络请求。
  • 数据库的读写。
  • 读取文件数据。

这些异步操作会返回一个Future对象,当数据量比较大的时候,会返回一个Stream对象。我们可以使用asyncawait关键字来处理这些异步操作返回的结果。

示例:使用异步函数的错误方式

如下代码展示了使用异步函数的错误方式,我们想打印 Your order is: Large Latte, 看一下如下代码,我们得到的输出结果是怎么样的?

String createOrderMessage() {
  var order = fetchUserOrder();
  return 'Your order is: $order';
}

Future<String> fetchUserOrder() =>
    // Imagine that this function is more complex and slow.
    Future.delayed(
      const Duration(seconds: 2),
      () => 'Large Latte',
    );

void main() {
  print(createOrderMessage());
}

输入结果为:

Your order is: Instance of '_Future<String>'

不是我们想要的结果,为什么?

  • fetchUserOrder()是一个异步函数,经过一小段时间,返回一个字符串: Large Latte
  • 为了得到字符串结果, createOrderMessage()函数,应该调用fetchUserOrder(),并且要等待该函数执行完成。在这里createOrderMessage()函数并没有等待fetchUserOrder()执行完成,所以order此时是一个_Future<String>对象。

异步:当开始执行时,在当前事情完成之前,可以做其他其他事情。
同步:同步操作会其完成之前,会阻塞其操作,不可以做其他事情。

什么是Future?

Future对象用来表示异步操作返回的结果,其有两种状态:未完成和完成

未完成

当调用一个异步函数时,会返回一个未完成的future对象,这个future正在等待异步操作完成或者抛出异常。

有返回值的完成状态

举个例子,Future<String>类型,在成功的完成状态下,其value值为一个 StringFuture<void>类型的future,在成功的完成状态下,无返回值。

错误

如果异步操作,发生了错误,future对象变变为一个error。

future示例

Future<void> fetchUserOrder() {
  // Imagine that this function is fetching user info from another service or database.
  return Future.delayed(const Duration(seconds: 2), () => print('Large Latte'));
}

void main() {
  fetchUserOrder();
  print('Fetching user order...');
}

输出结果为:

Fetching user order...
Large Latte

async,awiat

async关键字用来声明异步函数,await关键字用来表示等待使用异步返回的结果。使用asyncawait需要遵守以下两条规则

  • 定义异步函数,需要在函数体前面使用async关键字进行声明。
  • await只有在async函数中,才起作用。
Future<String> createOrderMessage() async {
  var order = await fetchUserOrder();
  return 'Your order is: $order';
}

Future<String> fetchUserOrder() =>
    // Imagine that this function is
    // more complex and slow.
    Future.delayed(
      const Duration(seconds: 2),
      () => 'Large Latte',
    );

Future<void> main() async {
  print('Fetching user order...');
  print(await createOrderMessage());
}

输出结果为

Fetching user order...
Your order is: Large Latte

相比较我们之前提到的错误示例,此时:

  • order实例由Future<String>变成了String
  • main 函数通过async 修饰,变为了异步函数。
  • createOrderMessage(),使用await关键字修饰,等待createOrderMessage()函数执行完成。

本篇关于future, async, await的介绍就到这里了,有兴趣的大家可以查阅Dart官方文档 aysnc-awit