join!() { /* proc-macro */ }
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 implementedFuture
instead of requiring it to be inside anasync
. 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 areUnpin
.
§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");