如果我有一些要链接在一起的期货,那么如何以第一个期货的结果为条件来使第二个链接的期货成为条件?
对于一个人为的例子,我有类似的东西:
extern crate futures;
extern crate tokio_core;
use futures::{future, Future};
use tokio_core::reactor::Core;
fn add_one(x: i64) -> impl Future<Item = i64, Error = ()> {
future::ok(x).map(|x| x + 1)
}
fn double(x: i64) -> impl Future<Item = i64, Error = ()> {
future::ok(x).map(|x| x * 2)
}
fn add_one_then_double(x: i64) -> impl Future<Item = i64, Error = ()> {
future::ok(x).and_then(add_one).and_then(double)
}
fn main() {
let mut reactor = Core::new().unwrap();
println!("{:?}", reactor.run(add_one_then_double(10)).unwrap());
}
然后如何更改add_one_then_double
的Future以add_one
的Future为条件,例如:
fn add_one_then_double_if_positive(x: i64) -> impl Future<Item = i64, Error = ()> {
future::ok(x).and_then(add_one).map(|v| {
if v >= 0 {
// chain the `double` future
} else {
// return `v` as the result
}
})
}
答案 0 :(得分:3)
如果要链接另一个未来,则需要使用and_then()
未来组合器,而不是map()
。该组合器期望另一个未来作为返回值,因此您的if
语句的两个分支都需要产生一个未来。在第一个分支中,您希望链接double(v)
,这已经是未来。在第二个分支中,您希望传递的值保持不变,因此您需要将其转换为可以使用v
立即解析为future::ok()
的将来。由于double(v)
和future::ok(v)
具有不同的类型,因此您需要使用future::Either
或对期货进行装箱。这是一个选择:
fn add_one_then_double(x: i64) -> impl Future<Item=i64, Error=()> {
future::ok(x)
.and_then(add_one)
.and_then(|v| {
if v >= 0 {
future::Either::A(double(v))
} else {
future::Either::B(future::ok(v))
}
})
}