dart - `FutureOr` 的目的是什么?

标签 dart

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/

相关文章:

string - 是否有更短的版本用于检查 Dart 中的空字符串和/或空字符串?

dictionary - 没有为类 '[]' 定义运算符 'Object' 。 Dart

javascript - 如何将 JavaScript 对象转换为 Dart Map?

在焦点上 flutter 文本字段背景颜色

flutter - 如何在下面的橙色矩形中居中放置标签?

firebase - Firestore查询不会因Geo flutter 火而返回附近的位置

firebase - Firebase身份验证和数据库规则

flutter - 在Flutter中创建类似于github语言栏的栏

database - 如何在 flutter 朔迷离的Cloud Firestore中获取当前自动生成的文档ID?

dart - Flutter 中的可拖动 FloatingActionButton