Async Iteration over Collection of .await-able T

Is there some native way of iterating over .await-able calls?

Or some collection to produce Stream for it's T like

 while let Some(r) = async_vec.next_async().await {
  // do stuff with r
}

For example lets consider this:

let mut a_vec: Vec<HasAwaitableMethod> = ...

// this will block on each run
for v in a_vec {
 //...
v.awaitable_method.await;
//...
}

let mut b_vec: AsyncVec<ImplNextAsync> = ...
// this should continue to next iteration asynchronously
while let Some(v) = async_vec.next_async().await {
  // do stuff with result when done
}

I'm not quite sure what you mean, but there's FuturesUnordered

async fn sleep(ms: u64) -> u64 {
    let dur = Duration::from_millis(ms);
    delay_for(dur).await;
    ms
}

#[tokio::main]
async fn main() {
    let mut futs = FuturesUnordered::new();
    
    futs.push(sleep(20));
    futs.push(sleep(5));
    futs.push(sleep(10));
    
    while let Some(item) = futs.next().await {
        println!("{}", item);
    }
}

playground

This prints

5
10
20
1 Like

Looks exactly what I need. Let me check with my code...

Any idea how to beat struct lifetime in this case?
playground

Did you link the wrong thing?

yup, here it is: playground

Here is a simplified version of the problem you are seeing:

fn main() {
    let mut vec: Vec<&str> = Vec::new();
    
    for i in 0..5 {
        let s = format!("{}", i);
        vec.push(&s);
        
        // s goes out of scope here
    }
    
    println!("{:?}", vec); // oops, s is used here
}

The ways to make it work are:

  1. Ensure that s is stored outside the loop.
  2. Make the thing in the collection take ownership of s.

In this case solution two is easiest, and there is a pretty easy way to do it:

for i in 0..10 {
    let mut s = S { v: 0 };
    futs.push(async move { s.sleep(10 * i).await });
}

playground

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.