我有以下方法:
pub fn load_names(&self, req: &super::MagicQueryType) -> ::grpcio::Result<::grpcio::ClientSStreamReceiver<String>> {
我的目标是获得grpcio::ClientSStreamReceiver
的第一个元素;我不在乎其他名称:
let name: String = load_names(query)?.wait().nth(0)?;
在wait()
之前调用nth(0)
似乎效率不高,因为我相信wait()
会阻塞流,直到接收到所有元素为止。
如何在不触发构建错误的情况下编写更有效的解决方案(即nth(0).wait()
)? Rust在futures::stream::Stream
上的构建错误令我感到非常困惑。
Rust playground不支持grpcio = "0.4.4"
,因此我无法提供链接。
答案 0 :(得分:2)
要以阻塞方式提取futures::Stream
的第一个元素,应通过调用Stream::wait
然后将Iterator::next
转换为Stream
到迭代器。阅读Stream::wait
的文档说明,它基本上是最有效的实现:
如果流中的项目尚未准备就绪,则此迭代器将在每次调用
next
时阻止当前线程。
use futures::{stream, Stream}; // 0.1.25
use std::iter;
fn example() -> impl Stream<Item = i32, Error = ()> {
stream::iter_ok(iter::repeat(42))
}
fn main() {
let v = example().wait().next();
println!("{:?}", v);
}
如果您使用的是Tokio,则可以将Stream
转换为Future
并致电Runtime::block_on
:
use std::iter;
use tokio::prelude::*; // 0.1.15
fn example() -> impl Stream<Item = i32, Error = ()> {
stream::iter_ok(iter::repeat(42))
}
fn main() {
let mut runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime");
let r = runtime.block_on(example().into_future());
if let Ok((v, _)) = r {
println!("{:?}", v);
}
}
另请参阅: