It'd be pretty nice for some of the stdlib methods that accept closures to have xyz_async
counterparts, that accept asynchronous closures, allowing you to continue using .await
just as you would in the parent scope (assuming the parent scope is an asynchronous function or closure).
Perhaps these would be best on separate traits, such as IteratorAsync<T>
or AsyncIterator<T>
as a counterpart for Iterator<T>
.
Consider the following example:
macro_rules! rint_api {
($t:ident) => {
&format!(r#"https://www.random.org/integers/?format=plain&col=1&base=10&min={min},&max={max}&num=1"#,
min = std::$i::MIN,
max = std::$t::MAX);
},
($min:literal > $t:ident max > $max:literal) => {
&format!(r#"https://www.random.org/integers/?format=plain&col=1&base=10&min={min},&max={max}&num=1"#,
min = $min,
max = $max);
},
}
thread_local! {
static FOO: RefCell<i32> = RefCell::new(0);
}
#[tokio::main]
async fn main() {
// Since this is an asynchronous function, you can use .await here...
FOO.with(|foo| {
// ... but not here, since this is a synchronous closure.
*foo += 42;
});
FOO.with_async(async move |foo| {
// Here, you _could_ use .await, since it is now an asynchronous closure.
// However, this method doesn't exist, hence why I'm making this post.
let to_add = match reqwest::get(rint_api!(-512 > i32 > 512)).await {
Ok(response) => match response.text().await() {
Ok(text) => match text.parse::<i32>() {
Ok(to_add) => to_add,
Err(error) => panic!(format!("{}", error)),
},
Err(error) => panic!(format!("{}", error)),
},
Err(error) => panic!(format!("{}", error)),
};
*foo += to_add;
}).await;
FOO.with_async(async move |foo| {
0..10.for_each_async(async move || {
let to_add = match reqwest::get(rint_api!(-512 > i32 > 512)).await {
Ok(response) => match response.text().await() {
Ok(text) => match text.parse::<i32>() {
Ok(to_add) => to_add,
Err(error) => panic!(error),
},
Err(error) => panic!(error),
},
Err(error) => panic!(error),
};
*foo += to_add;
}).await;
}).await;
}
Its worth noting that a workaround is possible, but it's much less ergonomic: ( Playground link ( Note: Broken, doesn't compile because of a CC error. Works if compiled locally. ) )
Now I know that asynchronous closures are still unstable, but this would be an amazing feature to have. Let me know what you all think!