Macro anony::join

source ·
join!() { /* proc-macro */ }
Available on crate feature future only.
Expand description

Returns a future that “joins” multiple futures that will be completed concurrently.

It’s output is a tuple of input futures’ outputs.

It is more efficient than awaiting futures like this: (fut1.await, fut2.await, fut3.await), since these futures will be resolved sequencially (fut1 must be done first before awaiting fut2, and fut3). join!(fut1, fut2, fut3).await will poll every futures on getting polled, which makes them concurrently awaited.

This future will always poll the first input future first, which is similar to the futures’s one. For example, join!(fut1, fut2, fut3) always polls fut1 first on being polled. If fairness is your concern, consider using join_cyclic!, which is less efficient but fairer.

§Possible differences from other implementations

  • join! returns an instance of an anonymous type implemented Future instead of requiring it to be inside an async. You will be warned if you neither .await, poll, nor return it.

  • input futures are required to implement IntoFuture.

  • the returned future (generally) has smaller size and is (generally) faster.

  • the returned future is Unpin if all of the input futures are Unpin.

§Examples

use anony::join;

let a = async { 1 };
let b = async { 2 };
let c = async { 3 };
assert_eq!(join!(a, b, c).await, (1, 2, 3));

If you want to run a future (or more) while doing something else, this macro is a help! Note that you must put the “something else” after every other futures you want to run:

use anony::join;
use tokio::time::sleep;
use std::time::Duration;

async fn read_db() -> String {
    sleep(Duration::from_secs(1)).await;
    "My secret".into()
}

let (secret_value, _) = join!(read_db(), async {
    // Your other tasks go here, maybe asynchronous or just blocking...
    let a = 1;
    let b = 2;
    assert_eq!(a + b, 3);
}).await;

assert_eq!(secret_value, "My secret");