tokio::spawn(my_future).await 和 my_future.await 有什么区别?

What is the difference between tokio::spawn(my_future).await and just my_future.await?

给定一个异步函数及其相应的 future,假设:

async fn foo() -> Result<i32, &'static str> {
    // ...
}

let my_future = foo();

仅使用 .await 等待它与使用 tokio::spawn().await 有什么区别?

// like this...
let result1 = my_future.await;

// ... and like this
let result2 = tokio::spawn(my_future).await;

人们通常不会等待生成的任务(或至少不会立即等待)。更常见的是简单地写:

tokio::spawn(my_future);

省略 .await 任务将 运行 在后台运行,同时当前任务继续进行。立即调用 .await 阻塞当前任务。 spawn(task).await 实际上与 task.await 没有什么不同。这类似于创建一个线程并立即加入它,这同样没有意义。

生成的任务不需要像 bare futures 那样等待。等待他们是可选的。那么什么时候可以等待呢?如果您想要阻止当前任务,直到生成的任务完成。

let task = tokio::spawn(my_future);

// Do something else.
do_other_work();

// Now wait for the task to complete, if it hasn't already.
task.await;

或者如果您需要结果,但需要在开始任务和收集结果之间做一些工作。

let task = tokio::spawn(my_future);

// Do something else.
do_other_work();

// Get the result.
let result = task.await;