如何解决future.then() 如何返回一个 Future?
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
。这怎么可能?
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 因为 Future
和 do_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 举报,一经查实,本站将立刻删除。