Hi!
I'm struggling to call an async function from a closure on an iterator - e.g. in a call to map. Here is a minimal contrived example that fails to compile. I'd like to end up with a collection (e.g. a Vec) after awaiting each of the async calls.
Am I missing something simple to make this work?
The normal way I would deal with the error is to wrap it in an async block - but then would have to explicitly poll the future manually. Can this be achieved with the await! syntax?
(Edited to make the actual issue more clear)
This can't work. You can use await only in async functions, but the closure is another different function and its not async, so you can't await in there.
Right. Thanks @kornel.
Is there an idomatic way to achieve the same goal?
i.e. I have an async function and I need to call it with each item from a collection, and collect the results.
Using futures-preview you can create an iterator of futures then collect them into a FuturesOrdered and collect the results back into a vector, something like
use futures::stream::{FuturesOrdered, StreamExt};
async fn runner() {
let results = await!((0..5).map(|i| do_something(i)).collect::<FuturesOrdered<_>>().collect::<Vec<_>>());
println!("Got {:?}", results);
}
use futures::future;
async fn runner() {
let results = await!(future::join_all((0..5).map(|i| do_something(i))));
println!("Got {:?}", results);
}
Depending on what sort of async operation you're doing and how many elements there are one or the other will be more efficient, but they should both work.
Ah thanks @Nemo157! That is exactly what I was looking for.
This also indirectly helped me discover the rename dependencies feature in cargo, as I had a bit of a muddle trying to use futures 0.1 (for some tokio stuff) and futures-preview together.
All solved, thanks.