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 教程。