FutureOr 可以等待 void 函数吗?

FutureOr can await void functions?

据我所知,不应该等待像 void foo() async {} 这样的函数,因为它们 return 没有可以等待的未来。但是我注意到,当我将它们分配给 FutureOr<void> Function() 字段时,可以等待它们。以下示例打印:PRE, FUNC, POST

import 'dart:async';

void func() async {
  await Future.delayed(const Duration(seconds: 2));
  
  print('FUNC');
}

Future<void> main() async {
  final FutureOr<void> Function() t = func;
  
  print('PRE');
  await t();
  print('POST');
}

我希望它打印:PRE,POST,FUNC

因为函数 func 不能等待(因为它 return 无效)因此 await t() 不应该等待 func 函数完成。

我观察到与 final dynamic Function() t = func;

相同的行为

我不确定这种行为是有意为之还是我只是不理解 void 异步函数?

如果您想跳过任务,请不要使用 await。在你的情况下使用 Future.sync()Future.microtask()Documentation

import 'dart:async';

void func() async {
  await Future.delayed(const Duration(seconds: 2));
  
  print('FUNC');
}

Future<void> main() async {
  final FutureOr<void> Function() t = func;
  
  print('PRE');
  Future.microtask(t);
  print('POST');
}

通过使用 await,您告诉编译器您要等到某些任务完成,而不管它是否 void

await 运算符可用于任何 对象 和除 void 之外的任何类型的表达式(这只是因为类型 void 在大多数情况下被明确禁止,而不是 await).

async 函数总是 return 是未来。即使它声明的 return 类型是 void。将 return 类型声明为 void 只是向用户发出信号,表明他们不应该期待有用的值,并且这使得实际获得该值变得更加困难(因为 above-mentioned 限制使用 void 键入的表达式).

事实上,所有 void return-type 函数 return 一个值(除非它们抛出)。该值通常为 null,但并非必须如此。 由于您可以在子类中使用 int foo() 覆盖 一个 void foo() 方法,并将 int Function() 分配给 void Function() 类型的变量,编译器实际上无法确定具有静态类型 void 的函数不会 return 任何东西。因此,它甚至不会尝试为本身类型为 returning void.

的函数强制执行它

类型 FutureOr<void>void(和 Future<void>)的超类型,因此 void Function() 函数对象可分配给类型 FutureOr<void> Function() .

总而言之,这共同使您的代码按照您看到的方式工作。 await t() 对具有静态类型 FutureOr<void> 和实际值为 Future<void> 的表达式执行 await,这是通过调用 return 编辑的 func。因此,await t() 等待 FUNC 被打印。