返回 void 与返回 Future<void> 有啥区别?

Posted

技术标签:

【中文标题】返回 void 与返回 Future<void> 有啥区别?【英文标题】:What's the difference between returning void vs returning Future<void>?返回 void 与返回 Future<void> 有什么区别? 【发布时间】:2019-10-08 04:28:55 【问题描述】:

返回voidasync 方法和返回Future&lt;void&gt; 的方法有区别吗?似乎两者在 Dart 中都有效:

void main() async 
    await myVoid();
    await myFutureVoid();



void myVoid() async 
    // Do something



Future<void> myFutureVoid() async 
    // Do something

它们是否相同?

如果是这样,为什么 void 被允许,而 int 则不允许?编译器说“标记为‘异步’的函数必须有一个可分配给‘未来’的返回类型”

【问题讨论】:

【参考方案1】:

void f()Future&lt;void&gt; f() 不相同。 (async 关键字的存在实际上并不重要。async 关键字主要允许在函数体中使用 await 关键字。)

void f() 声明了一个不返回任何内容的函数。如果它执行异步工作,那么该工作将是“即发即弃”:f 的调用者没有机会等待它完成。

相比之下,Future&lt;void&gt; f() 声明了一个函数,该函数返回调用者可以等待的Future(通过使用await 或通过注册Future.then() 回调)。异步工作没有返回值,但调用者可以确定何时完成。

标有async的函数通常应该返回Future。如果您有一个执行异步工作并产生实际值的函数(例如int),则调用者必须等待该值被计算后才能使用。因此,该函数必须返回 Future

作为一种特殊情况,async 函数可以返回 void 而不是 Future&lt;void&gt;,以表明它是即发即弃的。

【讨论】:

啊,我想我明白了。需要明确一点 - 如果 myVoid 使用 await 进行所有异步调用(即它基本上成为同步方法),那么 main 可以等待 myVoid完成……对吧?我认为这让我感到困惑,因为我遇到了这样一个函数并且无法弄清楚为什么它返回 void 而不是 Future&lt;void&gt;。尤其让我感到困惑的是 IntelliJ 提示 “仅等待期货。” - 但即使它返回 void,仍然可以等待该函数,就像将其更改为 Future&lt;void&gt; 一样... 虽然await myVoid(); 是合法的,但它与await myFutureVoid(); 不同。呼叫者将无法等待myVoid 完成。有一种特殊情况,Dart 虚拟机/运行时识别出有未完成的 Futures 并且在它们完成之前不会退出,这可能会使它看起来main 正在等待。但是,如果您执行了await myVoid(); print('foo');,您将看到foomyVoid 完成异步工作之前打印。 嗯,我不确定我是否理解正确 - 如果我做了 await myVoid(); print('foo');myVoid 在其所有异步操作上执行 await,则不会打印 foo 之后 myVoid返回?这就是我在之前评论中的意思。我制作了一个 Gist/Dartpad 示例来说明我的意思:dartpad.dartlang.org/b1acdb31305a1568cf33dc56e8df763f 嗯。我对当前的行为表示纠正。 supposed 是一个错误(但出于向后兼容性的原因还不是)。你应该避免awaiting void;它将来可能会中断(双关语不是故意的)。另见github.com/dart-lang/sdk/issues/28305 和github.com/dart-lang/sdk/issues/33415

以上是关于返回 void 与返回 Future<void> 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

异步支持返回不可链接的 Promise<void> 的函数

boost::async 只返回 void?

Vert.x Future 在检查状态时返回 false

Future<void> async 与 Dart 中的简单 void async

JAVA多线程学习十-Callable与Future的应用

Dart基础7-异步