为什么生成的期货没有被 tokio_core::reactor::Core 执行?
Why are spawned futures not executed by tokio_core::reactor::Core?
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
?
正如评论中已经提到的,您正在设置一堆计算,但从未 运行ning 任何一个。与迭代器一样,您可以将 futures 视为 lazy。当您直接创建未来但从未使用它时,编译器通常会告诉您这一点。在这里,您正在生成未来,因此您不会收到警告,但没有任何东西可以驱动 Tokio 反应堆。
在许多情况下,您有一个特定的未来想要运行,并且您会驾驶反应堆直到它完成。在其他情况下,您的 运行 反应器 "forever",无休止地处理新工作。
在这种情况下,您可以使用 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 中,您不需要(而且可能不应该)这样做。它优于 return 匿名类型:
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(())
}))
}
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
?
正如评论中已经提到的,您正在设置一堆计算,但从未 运行ning 任何一个。与迭代器一样,您可以将 futures 视为 lazy。当您直接创建未来但从未使用它时,编译器通常会告诉您这一点。在这里,您正在生成未来,因此您不会收到警告,但没有任何东西可以驱动 Tokio 反应堆。
在许多情况下,您有一个特定的未来想要运行,并且您会驾驶反应堆直到它完成。在其他情况下,您的 运行 反应器 "forever",无休止地处理新工作。
在这种情况下,您可以使用 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 中,您不需要(而且可能不应该)这样做。它优于 return 匿名类型:
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(())
}))
}