dart:async
库中Future
类的用法介绍如下。
异步计算的结果。
asynchronous computation
在启动时不能立即提供结果,这与同步计算不同,同步计算通过返回值或抛出来立即计算结果。异步计算可能需要等待程序外部的某些事情(读取文件、查询数据库、获取网页),这需要时间。在结果可用之前,异步计算不会阻塞所有计算,而是立即返回一个Future
,它将与结果一起eventually
"complete"。
异步编程
要执行异步计算,请使用 async
函数,该函数始终会产生未来。在这样的异步函数中,您可以使用await
操作来延迟执行,直到另一个异步计算有结果。在等待函数的执行被延迟的同时,程序并没有被阻塞,可以继续做其他事情。
例子:
import "dart:io";
Future<bool> fileContains(String path, String needle) async {
var haystack = await File(path).readAsString();
return haystack.contains(needle);
}
这里来自 dart:io
的 File.readAsString
方法是一个返回 Future<String>
的异步函数。 fileContains
函数在其主体之前标有async
,这意味着您可以在其中使用await
,并且它必须返回一个未来。对File(path).readAsString()
的调用启动将文件读入字符串并生成最终包含结果的Future<String>
。然后 await
等待该未来以字符串完成(或错误,如果读取文件失败)。在等待期间,程序可以做其他事情。当 future 以字符串结束时,fileContains
函数计算一个布尔值并返回它,然后完成它在第一次调用时返回的原始未来。
如果未来以 error
完成,则等待该未来将(重新)抛出该错误。在这里的示例中,我们可以添加错误检查:
import "dart:io";
Future<bool> fileContains(String path, String needle) async {
try {
var haystack = await File(path).readAsString();
return haystack.contains(needle);
} on FileSystemException catch (exception, stack) {
_myLog.logError(exception, stack);
return false;
}
}
您使用普通的 try
/catch
来捕获等待的异步计算的失败。
一般来说,在编写异步代码时,你应该总是等待一个未来的产生,而不是等到另一个异步延迟之后。这可确保您准备好接收未来可能产生的任何错误,这一点很重要,因为 no-one 正在等待的异步错误是 uncaught
错误,并且可能会终止正在运行的程序。
使用Future
API 进行编程。
Future
类还提供了更直接的低级函数来访问它完成的结果。 async
和await
语言特性建立在此函数之上,有时直接使用它是有意义的。有些事情你不能通过一次await
ing 一个未来来完成。
使用 Future ,您可以手动注册处理值或错误的回调(一旦可用)。例如:
Future<int> future = getFuture();
future.then((value) => handleValue(value))
.catchError((error) => handleError(error));
由于 Future 可以通过两种方式完成,使用值(如果异步计算成功)或错误(如果计算失败),您可以为其中一种或两种情况安装回调。
在某些情况下,我们说未来已完成 with another future
。这是一种简短的方式来说明未来以相同的方式完成,具有相同的值或错误,一旦另一个未来本身完成,另一个未来。完成未来的平台库中的大多数函数(例如 Completer.complete 或 Future.value )也接受另一个未来,并自动处理将结果转发到正在完成的未来。
注册回调的结果本身就是一个 Future
,它反过来通过使用原始未来结果调用相应回调的结果来完成。如果调用的回调抛出,则新的未来完成并出现错误。例如:
Future<int> successor = future.then((int value) {
// Invoked when the future is completed with a value.
return 42; // The successor is completed with the value 42.
},
onError: (e) {
// Invoked when the future is completed with an error.
if (canHandle(e)) {
return 499; // The successor is completed with the value 499.
} else {
throw e; // The successor is completed with the error e.
}
});
如果未来在完成错误时没有任何注册的处理程序,它会将错误转发到“uncaught-error 处理程序”。此行为可确保不会以静默方式丢弃任何错误。但是,这也意味着应该尽早安装错误处理程序,以便它们在未来完成时出现错误。以下示例演示了这个潜在的错误:
var future = getFuture();
Timer(const Duration(milliseconds: 5), () {
// The error-handler is not attached until 5 ms after the future has
// been received. If the future fails before that, the error is
// forwarded to the global error-handler, even though there is code
// (just below) to eventually handle the error.
future.then((value) { useValue(value); },
onError: (e) { handleError(e); });
});
注册回调时,分别注册两个回调通常更具可读性,首先使用带有一个参数(值处理程序)的then,然后使用第二个catchError 来处理错误。它们中的每一个都会将它们不处理的结果转发给它们的后继者,它们一起处理值和错误结果。它还具有 catchError 处理 then 值回调中的错误的额外好处。使用顺序处理程序而不是并行处理程序通常会导致代码更容易推理。它还使异步代码与同步代码非常相似:
// Synchronous code.
try {
int value = foo();
return bar(value);
} catch (e) {
return 499;
}
基于期货的等效异步代码:
Future<int> asyncValue = Future(foo); // Result of foo() as a future.
asyncValue.then((int value) {
return bar(value);
}).catchError((e) {
return 499;
});
与同步代码类似,错误处理程序(使用 catchError 注册)正在处理由 foo
或 bar
引发的任何错误。如果 error-handler 已注册为 then
调用的 onError
参数,则它不会捕获来自 bar
调用的错误。
期货可以注册多个callback-pair。每个后继者都被独立对待,并被视为唯一的后继者。
未来也可能永远无法完成。在这种情况下,不会调用回调。如果可能的话,通常应该避免这种情况,除非它有非常清楚的记录。
- 可用的扩展
相关用法
- Dart Future.doWhile用法及代码示例
- Dart Future.any用法及代码示例
- Dart Future.value用法及代码示例
- Dart Future.wait用法及代码示例
- Dart Future.whenComplete用法及代码示例
- Dart Future.catchError用法及代码示例
- Dart Future.error用法及代码示例
- Dart Future.timeout用法及代码示例
- Dart Future.sync用法及代码示例
- Dart Future.delayed用法及代码示例
- Dart FutureExtensions.onError用法及代码示例
- Dart Function.apply用法及代码示例
- Dart FileList.first用法及代码示例
- Dart FileList.length用法及代码示例
- Dart File用法及代码示例
- Dart Finalizer.attach用法及代码示例
- Dart Float32List.view用法及代码示例
- Dart FileSystemEntity用法及代码示例
- Dart FileSystemEntity.resolveSymbolicLinks用法及代码示例
- Dart Finalizable用法及代码示例
- Dart File.renameSync用法及代码示例
- Dart Float32x4List.sublist用法及代码示例
- Dart Finalizer用法及代码示例
- Dart FileSystemEntity.resolveSymbolicLinksSync用法及代码示例
- Dart FileList.elementAt用法及代码示例
注:本文由纯净天空筛选整理自dart.dev大神的英文原创作品 Future<T> class。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。