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
吗?
答案 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::run
和tokio::spawn
:
fn main() {
tokio::run(futures::lazy(|| {
for _ in 0..10 {
tokio::spawn(create_a_future());
}
Ok(())
}))
}