Dart Future
最后修改日期:2024 年 1 月 28 日
在本文中,我们将展示如何在 Dart 语言中使用 Future。
Future
一个 Future 代表一个未来某个时间点可能可用(或出错)的值。
Future 可以成功返回一个值,也可以抛出一个错误。程序员可以为这两种情况注册回调函数。Future 以及 async
和 await
关键字用于在 Dart 中执行异步操作。
常见的异步操作包括
- 通过网络获取数据
- 从数据库读取数据
- 从文件中读取数据
- 在 UI 程序中执行耗时任务
async
和 await
关键字提供了一种声明式的方式来定义异步函数并使用它们的结果。我们用 async
关键字标记一个异步函数。await
关键字用于获取异步表达式的已完成结果。await 关键字只能在异步函数内部使用。
一些语言使用术语 Promise 来表示相同的功能。
Dart Future 简单示例
Future.value
创建一个已成功完成并带有值的 Future。
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。
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 在文件内容读取完成后,用字符串完成。
bear fruit cloud sky forest falcon wood lake rock
这是 words.txt
文件。
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 都完成后完成。
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
在下面的示例中,我们检查目录是否存在。
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
包。
name: app environment: sdk: '>=2.18.0 <3.0.0' dependencies: http: ^0.13.5
这是 pubspec.yaml
。
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 教程。