Dart 提供 FutureOr类,允许编写:
FutureOr<int> future;
future = 42; // valid
future = Future.value(42); // also valid
我认为 FutureOr如果可以同步读取值,则可用于消除由事件循环引起的不必要的延迟。
但事实似乎并非如此,如下所示:
import 'dart:async';
void main() async {
print('START');
futureOrExample();
print('END');
}
void futureOrExample() async {
FutureOr<int> futureOr = 42;
print('before await');
await futureOr;
print('end await');
}
打印:
START
before await
END
end await
当我期望:
START
before await
end await
END
既然如此,为什么FutureOr (或更一般地说
await 42
)以这种方式工作?同样,FutureOr的目的是什么?在这种情况下,因为它产生与 Future 相同的结果?
我知道我可以使用 SynchronousFuture达到预期的结果,但我只是想了解 FutureOr 的用途是什么.
最佳答案
FutureOr
的使用,正如 Dart 2 引入的那样,允许您在现有的 Dart 1 API 允许相同的事情的点上提供值或 future ,以方便起见,只能以可以静态类型的方式。
规范示例是 Future.then
. Future<T>
上的签名是 Future<R> then<R>(FutureOr<R> action(T value), {Function onError})
.
这个想法是你可以对 future 的值(value)采取同步或异步的行动。原来有一个then
接受同步回调和 chain
的函数函数采用异步回调,但使用起来非常烦人,在良好的 Dart 1 风格中,API 减少到一个 then
接受函数返回 dynamic
的方法,然后它检查它是否是 future 。
在 Dart 1 中,很容易让你返回一个值或一个 future 。 Dart 2 没有那么宽松,所以 FutureOr
引入类型是为了允许现有的 API 继续工作。如果我们从头开始编写 API,我们可能会做其他事情,但是将现有的异步代码库迁移到完全不同的东西是不可行的,因此 FutureOr
type 是作为类型级别的 hack 引入的。await
操作最初也被定义为对任何对象起作用,早在 FutureOr
之前存在。为了一致性和更小的代码,await e
哪里e
评估为非 future 将在 future 包装该值并等待它。这意味着对一个值只有一个快速且可重用的检查(它是一个 future ,如果没有包装它),然后剩下的代码是一样的。只有一个代码路径。
如果await
在非 Future
上同步工作值,必须有一个通过 await
运行的同步代码路径。 ,以及等待 future 的异步路径。这可能会使代码大小增加一倍,例如在编译为 JavaScript 时(或者更糟的是,如果在同一控制流中有更多 await
s,您可能会因幼稚的实现而指数级增长)。即使您仅通过同步调用延续函数来避免这种情况,一些读者也可能会混淆 await
不会引入异步间隙。周围的错误可能导致竞争条件或以错误的顺序发生的事情。
所以,原始设计,早于 FutureOr
,是为了使所有await
操作实际上等待。
简介FutureOr
没有改变这个推理,即使它改变了,在人们期望他们的代码实际上给其他微任务运行时间的地方不等待,现在也将是一个突破性的变化。
关于dart - `FutureOr` 的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59213196/