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>>
.
的所有个体期货
下面的函数,取自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 是
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
.
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>>
.