Skip to content

Add Future::join #14

Closed
Closed
@yoshuawuyts

Description

@yoshuawuyts

In the 2016 futures announcement post, the join combinator was shown as something that would make choosing between several futures easy.

In rust-lang/futures-rs#1215 and beyond this was changed to several methods: join, join1, join2, join3, and join!, try_join macros (proc macros since 0.3.0-alpha.18 so statements can be written inline).

Future::join

It still seems incredibly useful to be able to join multiple futures together, and having a single combinator to do that seems like the simplest API, even if resulting code might not look completely symmetrical. I propose we add Future::join:

use async_std::future;

let a = future::ready(1);
let b = future::ready(2);
let pair = a.join(b);

assert_eq!(pair.await, (1, 2));

Future::try_join

The futures-preview library also exposes a try_join method. This is useful when you want to unwrap two results. Internally it uses TryFuture as a reference, which means this method should only exist on futures where Output = Result<T, E>, and I'm not entirely sure if that's feasible. However if it is it might be convenient to also expose:

use async_std::future;

let a = future::ready(Ok::<i32, i32>(1));
let b = future::ready(Ok::<i32, i32>(2));
let pair = a.try_join(b);

assert_eq!(pair.await, Ok((1, 2)));

Future::join_all

The third join combinator present is Future::join_all. The docs don't make a big sell on them (inefficient, set can't be modified after polling started, prefer futures_unordered), but it's probably still worth mentioning. I don't think we should add this combinator, but instead point people to use fold instead:

don't do this

use async_std::future::join_all;

async fn foo(i: u32) -> u32 { i }
let futures = vec![foo(1), foo(2), foo(3)];

assert_eq!(join_all(futures).await, [1, 2, 3]);

do this instead

let futures = vec![foo(1), foo(2), foo(3)];
let futures = futures.fold(|p, n| p.join(n))
assert_eq!(futures.await, [1, 2, 3]);

note: not tested this, but in general I don't think we need to worry about this case too much as handling the unordered case seems much more important and would cover this too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions