2

如果我有一些要链接在一起的期货,我怎样才能使第二个链接的未来以第一个未来的结果为条件?

对于一个人为的例子,我有类似的东西:

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未来的结果为条件add_one,例如:

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
        }
    })
}
4

1 回答 1

4

如果你想链接另一个未来,你需要使用and_then()未来组合器,而不是map(). 这个组合器期望另一个未来作为返回值,所以你的语句的两个分支都if需要产生一个未来。在第一个分支中,您想要链接double(v),这已经是一个未来。在第二个分支中,您希望传递不变的值,因此您需要将其转换为立即解析为vusing的未来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))
            }
        })
}

操场

于 2018-11-02T13:24:10.253 回答