Is there any way to create a async stream generator that yields the result of repeatedly calling a function?

前端 未结 1 1333
猫巷女王i
猫巷女王i 2020-12-17 06:22

I want to build a program that collects weather updates and represents them as a stream. I want to call get_weather() in an infinite loop, with 60 seconds delay

相关标签:
1条回答
  • 2020-12-17 06:47

    Use stream::unfold to go from the "world of futures" to the "world of streams". We don't need any extra state, so we use the empty tuple:

    use futures::StreamExt; // 0.3.4
    use std::time::Duration;
    use tokio::time; // 0.2.11
    
    struct Weather;
    
    async fn get_weather() -> Weather {
        Weather
    }
    
    const BETWEEN: Duration = Duration::from_secs(1);
    
    fn get_weather_stream() -> impl futures::Stream<Item = Weather> {
        futures::stream::unfold((), |_| async {
            time::delay_for(BETWEEN).await;
            let weather = get_weather().await;
            Some((weather, ()))
        })
    }
    
    #[tokio::main]
    async fn main() {
        get_weather_stream()
            .take(3)
            .for_each(|_v| async {
                println!("Got the weather");
            })
            .await;
    }
    
    % time ./target/debug/example
    
    Got the weather
    Got the weather
    Got the weather
    
    real    3.085   3085495us
    user    0.004   3928us
    sys     0.003   3151us
    

    See also:

    • How do I convert an iterator into a stream on success or an empty stream on failure?
    • How do I iterate over a Vec of functions returning Futures in Rust?
    • Creating a stream of values while calling async fns?
    0 讨论(0)
提交回复
热议问题