微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

future.then() 如何返回一个 Future?

如何解决future.then() 如何返回一个 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 {
         ...

应该返回一个 Future。然而,它返回了

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

.then 在何处执行此操作:

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

这不是 Future。这怎么可能?

我正在尝试了解此函数返回的内容。这是'.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)))
            }
        })),

看起来它返回了 Either::Right(Either::Right 的东西。我很困惑。

解决方法

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


Either 类型旨在将具有相同关联输出的两个不同期货组合成一个类型。假设您正在创建一个函数,它将根据输入返回两个不同的未来:

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 因为 Futuredo_a() 返回的 do_b()不同类型。 Rust 编译器很友好地建议使用 Box<dyn Future> 来动态返回不同的类型,但是有时出于性能原因不需要额外的间接访问,也没有必要。

上面可以实现为使用 Future 返回一个具体的 Either

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>>>,因为它可能产生的所有单个期货都会返回一个 Result<Pooled<PoolClient<B>>,ClientError<B>>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。