返回 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 【问题描述】:返回void
的async
方法和返回Future<void>
的方法有区别吗?似乎两者在 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<void> f()
不相同。 (async
关键字的存在实际上并不重要。async
关键字主要允许在函数体中使用 await
关键字。)
void f()
声明了一个不返回任何内容的函数。如果它执行异步工作,那么该工作将是“即发即弃”:f
的调用者没有机会等待它完成。
相比之下,Future<void> f()
声明了一个函数,该函数返回调用者可以等待的Future
(通过使用await
或通过注册Future.then()
回调)。异步工作没有返回值,但调用者可以确定何时完成。
标有async
的函数通常应该返回Future
。如果您有一个执行异步工作并产生实际值的函数(例如int
),则调用者必须等待该值被计算后才能使用。因此,该函数必须返回 Future
。
作为一种特殊情况,async
函数可以返回 void
而不是 Future<void>
,以表明它是即发即弃的。
【讨论】:
啊,我想我明白了。需要明确一点 - 如果myVoid
使用 await
进行所有异步调用(即它基本上成为同步方法),那么 main
可以等待 myVoid
完成……对吧?我认为这让我感到困惑,因为我遇到了这样一个函数并且无法弄清楚为什么它返回 void
而不是 Future<void>
。尤其让我感到困惑的是 IntelliJ 提示 “仅等待期货。” - 但即使它返回 void
,仍然可以等待该函数,就像将其更改为 Future<void>
一样...
虽然await myVoid();
是合法的,但它与await myFutureVoid();
不同。呼叫者将无法等待myVoid
完成。有一种特殊情况,Dart 虚拟机/运行时识别出有未完成的 Future
s 并且在它们完成之前不会退出,这可能会使它看起来像 main
正在等待。但是,如果您执行了await myVoid(); print('foo');
,您将看到foo
在myVoid
完成异步工作之前打印。
嗯,我不确定我是否理解正确 - 如果我做了 await myVoid(); print('foo');
和 myVoid
在其所有异步操作上执行 await
,则不会打印 foo
之后 myVoid
返回?这就是我在之前评论中的意思。我制作了一个 Gist/Dartpad 示例来说明我的意思:dartpad.dartlang.org/b1acdb31305a1568cf33dc56e8df763f
嗯。我对当前的行为表示纠正。 supposed 是一个错误(但出于向后兼容性的原因还不是)。你应该避免await
ing void
;它将来可能会中断(双关语不是故意的)。另见github.com/dart-lang/sdk/issues/28305 和github.com/dart-lang/sdk/issues/33415以上是关于返回 void 与返回 Future<void> 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章