future.then() return 如何才能成为未来?

How can future.then() return a Future?

下面的函数,取自here

fn connection_for(
    &self,
    pool_key: PoolKey,
) -> impl Future<Output = Result<Pooled<PoolClient<B>>, ClientError<B>>> {

    let checkout = self.pool.checkout(pool_key.clone());
    let connect = self.connect_to(pool_key);

    let executor = self.conn_builder.exec.clone();
    // The order of the `select` is depended on below...
    future::select(checkout, connect).then(move |either| match either {
         ...

应该return一个Future。但是,它 return 是

的 return 结果
    future::select(checkout, connect).then(...)

.then 这样做的地方:

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>

这不是 Future。这怎么可能?

我正在尝试了解此函数 return 编辑的内容。这是'.then'的结尾:

       Either::Right((Err(err), checkout)) => Either::Right(Either::Right({
            if err.is_canceled() {
                Either::Left(checkout.map_err(ClientError::Normal))
            } else {
                Either::Right(future::err(ClientError::Normal(err)))
            }
        })),

它看起来像是 returns Either::Right(Either::Right 的东西。我很困惑。

.then() 用于将两个期货链接在一起。它 return 是一个 Then<Fut1, Fut2, F>,这是一个 Future,它完成以下工作:轮询第一个未来,使用给定函数处理结果,并轮询结果未来。


Either 类型旨在将具有相同关联输出的两个不同期货组合成一个类型。假设您正在制作一个函数,该函数将 return 两种不同的未来取决于输入:

async fn do_a() -> () {}
async fn do_b() -> () {}

fn do_something(cond: bool) -> impl Future<Output = ()> {
    if cond {
        do_a()
    }
    else {
        do_b()
    }
}

This won't compile 因为 do_a()do_b() 编辑的 Future 和 return 是 不同的类型 。 Rust 编译器非常友好地建议动态使用 Box<dyn Future> 到 return 不同的类型,但是出于性能原因有时不需要额外的间接寻址,也没有必要。

以上可以使用 Either.

实现 return 一个具体的 Future
use std::future::Future;
use futures::future::Either;

async fn do_a() -> () {}
async fn do_b() -> () {}

fn do_something(cond: bool) -> impl Future<Output = ()> {
    if cond {
        Either::Left(do_a())
    }
    else {
        Either::Right(do_b())
    }
}

有问题的链接代码看起来有点粗糙,因为它不仅要协调两个不同的未来,还要协调五个。但是您可以毫无问题地嵌套 Either,因为它们本身就是 Future。它更像这样:

use std::future::Future;
use futures::future::Either;

async fn do_a() -> () {}
async fn do_b() -> () {}
async fn do_c() -> () {}
async fn do_d() -> () {}
async fn do_e() -> () {}

fn do_something(cond1: bool, cond2: bool, cond3: bool) -> impl Future<Output = ()> {
    if cond1 {
        Either::Left(do_a())
    }
    else if cond2 {
        if cond3 {
            Either::Right(Either::Left(Either::Left(do_b())))
        }
        else {
            Either::Right(Either::Left(Either::Right(do_c())))
        }
    }
    else {
        if cond3 {
            Either::Right(Either::Right(Either::Left(do_d())))
        }
        else {
            Either::Right(Either::Right(Either::Right(do_e())))
        }
    }
}

这一切最终都会创造一个 impl Future<Output = Result<Pooled<PoolClient<B>>, ClientError<B>>>,因为它可能会产生每个 return 个 Result<Pooled<PoolClient<B>>, ClientError<B>>.

的所有个体期货