await in Rust

Nilesh Katuwal Jul 04, 2022
await in Rust

In this article, we will learn the meaning of await in Rust.

await in Rust

async-await is a technique for writing functions that can pause, surrender control to the runtime, and then resume execution where they left off. Typically, these pauses are used to await I/O, but they can serve various purposes.

async-await may be familiar to you from JavaScript or C#. However, Rust’s implementation of the functionality has a few important changes.

To utilize async-await, you must replace fn with async fn:

async fn new_fxn() -> u32 { .. }

In contrast to a conventional function, calling an async fn has no immediate effect. It returns a future instead.

The computation is suspended and waiting to be executed. Use the .awaitoperator to execute the future:

async fn second_fxn () {
    let future = new_fxn();

    let result: u32 = future.await;
    ...
}

This example illustrates the first distinction between Rust and other languages: we write future.await rather than await future. This syntax interacts better with Rust’s ? operator for propagating errors, which are common in I/O.

You can write future.await? to bear faults and await the result of a lot. Additionally, it has the benefit of making the method of chaining painless.

The term await can only be used within the context of asynchronous functions, and only asynchronous functions can be awaited.

Rust’s futures are lax; by default, they will do nothing before the first poll is conducted. When you await the future, it is surveyed.

For instance, if you call a function that returns a future at the beginning of your program but does not await it until the end of the program, the actual request will not be executed until you await it.

Example:

use std::thread;
use tokio::time::{sleep, Duration};
use futures::future;

#[tokio::main]
async fn main(){
    let mut await_demo = Vec::new();

    for count in 1..=5
    {
        await_demo.push(tokio::spawn(async move{
            println!("Start the thread {count}, id= {:?}", thread::current().id());
            sleep (Duration::from_millis(5000)).await;
            println!("end the thread {count}, id = {:?})", thread::current().id());
        }));
    }
    future::join_all (await_demo).await;
}

First, five futures (five async blocks) are created, with each future creating a sleep future and calling await on it. These futures exist concurrently.

Each block displays the thread id before and following await.

Output:

Standard Output
Start the thread 1, id= ThreadId(2)
Start the thread 3, id= ThreadId(2)
Start the thread 4, id= ThreadId(2)
Start the thread 5, id= ThreadId(2)
Start the thread 2, id= ThreadId(3)
end the thread 2, id = ThreadId(2))
end the thread 3, id = ThreadId(3))
end the thread 1, id = ThreadId(3))
end the thread 4, id = ThreadId(3))
end the thread 5, id = ThreadId(3))