为什么生成的期货不由tokio_core :: reactor :: Core执行?

时间:2018-10-26 21:53:19

标签: rust rust-tokio

extern crate tokio; // 0.1.8

use tokio::prelude::*;

fn create_a_future(x: u8) -> Box<Future<Item = (), Error = ()>> {
    Box::new(futures::future::ok(2).and_then(|a| {
        println!("{}", a);
        Ok(())
    }))
}

fn main() {
    let mut eloop = tokio_core::reactor::Core::new().unwrap();
    let handle = eloop.handle();

    for x in 0..10 {
        let f = create_a_future(x);
        handle.spawn(f);
    }
}

我希望将其打印到标准输出,但是没有发生。我使用错误的方式使用spawn吗?

1 个答案:

答案 0 :(得分:1)

正如评论中已经提到的那样,您正在设置大量计算,但从未运行任何计算。像迭代器一样,您可以将期货视为 lazy 。当您直接创建未来但从不使用它时,编译器通常会告诉您有关此的信息。在这里,您正在生成期货,因此您不会收到该警告,但是没有任何东西可以驱动Tokio反应堆。

在许多情况下,您有一个特定的未来要运行,您将驾驶反应堆直到完成。在其他情况下,您将“永远”运行反应堆,从而无休止地处理新工作。

在这种情况下,您可以使用Core::turn

fn main() {
    let mut eloop = tokio_core::reactor::Core::new().unwrap();
    let handle = eloop.handle();

    for x in 0..10 {
        let f = create_a_future(x);
        handle.spawn(f);
    }

    eloop.run(None);
}

eloop.turn(None);

-> Box<Future<Item = (), Error = ()>>

您不需要(也许应该)在现代Rust中做到这一点。最好返回一个匿名类型:

fn create_a_future() -> impl Future<Item = (), Error = ()> {
    futures::future::ok(2).and_then(|a| {
        println!("{}", a);
        Ok(())
    })
}
 tokio_core::reactor::Core

我的理解是,此级别的Tokio保留用于更复杂的设置。许多人只能使用tokio::runtokio::spawn

fn main() {
    tokio::run(futures::lazy(|| {
        for _ in 0..10 {
            tokio::spawn(create_a_future());
        }
        Ok(())
    }))
}