在 JavaScript 中,异步代码是用类似于 Rust 的Promise 和async/await语法编写的。当 Promise 可以简单地返回时(即,当异步函数作为另一个函数中的最后一件事执行时),返回并等待 Promise通常被认为是多余的(因此不鼓励):
async function myFn() { /* ... */ }
async function myFn2() {
// do setup work
return await myFn()
// ^ this is not necessary when we can just return the Promise
}
Run Code Online (Sandbox Code Playgroud)
我想知道类似的模式是否适用于 Rust。我应该更喜欢这个:
pub async fn my_function(
&mut self,
) -> Result<()> {
// do synchronous setup work
self.exec_command(
/* ... */
)
.await
}
Run Code Online (Sandbox Code Playgroud)
或这个:
pub fn my_function(
&mut self,
) -> impl Future<Output = Result<()>> {
// do synchronous setup work
self.exec_command(
/* ... */
)
}
Run Code Online (Sandbox Code Playgroud)
前者对我来说更符合人体工程学,但我怀疑后者的性能可能更高。是这种情况吗?
两个变体之间的一个语义差异是,在第一个变体中,同步设置代码仅在等待返回的 future 时运行,而在第二个变体中,它将在调用函数后立即运行:
let fut = x.my_function();
// in the second variant, the synchronous setup has finished by now
...
let val = fut.await; // in the first variant, it runs here
Run Code Online (Sandbox Code Playgroud)
为了使差异变得明显,同步设置代码必须有副作用,并且在调用异步函数和等待它返回的 future 之间需要有延迟。
除非您有特定原因立即执行前导码,否则请使用异步函数,即第一个变体。它使函数稍微更具可预测性,并且在函数重构时更容易添加更多等待。