ZetCode

Dart Future

最后修改日期:2024 年 1 月 28 日

在本文中,我们将展示如何在 Dart 语言中使用 Future。

Future

一个 Future 代表一个未来某个时间点可能可用(或出错)的值。

Future 可以成功返回一个值,也可以抛出一个错误。程序员可以为这两种情况注册回调函数。Future 以及 asyncawait 关键字用于在 Dart 中执行异步操作。

常见的异步操作包括

asyncawait 关键字提供了一种声明式的方式来定义异步函数并使用它们的结果。我们用 async 关键字标记一个异步函数。await 关键字用于获取异步表达式的已完成结果。await 关键字只能在异步函数内部使用。

一些语言使用术语 Promise 来表示相同的功能。

Dart Future 简单示例

Future.value 创建一个已成功完成并带有值的 Future。

main.dart
void main() async {
  final myfut1 = Future.value(14);
  print(myfut1);

  final myfut2 = await Future.value(14);
  print(myfut2);
}

在示例中,我们有两个 Future。

void main() async {

由于我们在 main 函数中处理 Future,因此我们用 async 关键字标记它。

final myfut1 = Future.value(14);
print(myfut1);

这段代码是不正确的;我们用 Future.value 创建了一个新的 Future 并打印了结果,结果是一个未完成的 Future 实例。为了获取值,我们需要使用 await 关键字。

var myfut2 = await Future.value(14);
print(myfut2);

我们创建了另一个 Future,并使用 await 关键字等待其结果。

$ dart main.dart
Instance of 'Future<int>'
14  

Dart Future.delayed

Future.delayed 创建一个在延迟后执行其计算的 Future。

main.dart
void main() async {
  Future.delayed(Duration(seconds: 2), () => 12).then((value) => print(value));

  final res = await Future.delayed(Duration(seconds: 2), () => 14);
  print(res);
}

该示例创建了两个延迟的 Future。

Future.delayed(Duration(seconds: 2), () => 12).then((value) => print(value));

我们创建了一个在两秒后执行的 Future;它返回值为 12。使用 then,我们注册了一个 Future 完成时的回调。它会将返回的值打印到控制台。

final res = await Future.delayed(Duration(seconds: 2), () => 14);
print(res);

执行了相同的功能;这次使用了 await 关键字。

$ dart main.dart
12
14

Dart 使用 readAsString 读取文件

readAsString 函数以异步方式将整个文件内容读取为字符串。它返回一个 Future<String>,该 Future 在文件内容读取完成后,用字符串完成。

words.txt
bear
fruit
cloud
sky
forest
falcon
wood
lake
rock

这是 words.txt 文件。

main.dart
import 'dart:io';

void main() async {
  final file = File('words.txt');

  final contents = await file.readAsString();
  print(contents);
}

该示例异步读取 words.txt 文件。

Dart Future.wait

Future.wait 等待多个 Future 完成并收集它们的结果。它返回一个 Future,该 Future 在所有给定的 Future 都完成后完成。

main.dart
import 'dart:async';
import 'dart:math';

Future<int> getRandomValue() async {
  await Future.delayed(Duration(seconds: 1));
  final random = new Random();
  return random.nextInt(150);
}

int findMinVal(List<int> lst) {
  lst.forEach((e) => print(e));

  return lst.reduce(max);
}

void main() async {
  final maximum = await Future.wait([
    getRandomValue(),
    getRandomValue(),
    getRandomValue(),
    getRandomValue(),
    getRandomValue(),
    getRandomValue()
  ]).then((List<int> results) => findMinVal(results));

  print('Maximum is : $maximum');
}

在示例中,我们有一个异步的 getRandomValue 方法,它返回一个随机值。我们启动该方法六次,并将它们全部放在 Future.wait 中。所有 Future 完成后,我们找出生成的随机值中的最大值。

$ dart main.dart
94
13
106
41
110
122
Maximum is : 122

在下面的示例中,我们检查目录是否存在。

main.dart
import 'dart:io';

void main() async {
  final path = 'doc/crypto';
  final dr = Directory(path);

  final present = await dr.exists();

  if (present) {
    print('directory exists');
    Future.wait([dr.delete()]).then((_) => checkIfExists(dr));
  } else {
    print('directory does not exist');
  }
}

void checkIfExists(Directory dr) async {
  final present = await dr.exists();
  print(present ? 'directory exists' : 'directory does not exist');
}

如果给定目录存在,我们就删除它,然后再次检查它是否存在。

Future.wait([dr.delete()]).then((_) => checkIfExists(dr));

使用 Future.wait,我们等待目录被删除。只有在异步操作完成后,我们才调用 checkIfExists

Dart Future GET 请求

http 是一个可组合的、基于 Future 的库,用于发出 HTTP 请求。

$ dart pub add http

我们添加 http 包。

pubspec.yaml
name: app

environment:
    sdk: '>=2.18.0 <3.0.0'
dependencies:
    http: ^0.13.5

这是 pubspec.yaml

main.dart
import 'package:http/http.dart' as http;

Future<String> fetchData() async {
  final resp = await http.get(Uri.http('webcode.me'));

  if (resp.statusCode == 200) {
    return resp.body;
  } else {
    throw Exception('Failed to fetch data');
  }
}

void main() async {
  final data = await fetchData();
  print(data);
}

在示例中,我们向 webcode.me 发送了一个 GET 请求,并打印了响应体。

$ dart main.dart
<!DOCTYPE html>
<html lang="en">
<head>
...

来源

Dart Future - 语言参考

在本文中,我们学习了如何在 Dart 中使用 Future。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直撰写编程文章。迄今为止,我已撰写超过 1400 篇文章和 8 本电子书。我在编程教学方面拥有超过十年的经验。

列出 所有 Dart 教程