Как выполнить сразу несколько асинхронных функций и получить результат?
Я пробовал задачи Tokio, но нет рабочих примеров для одновременного выполнения нескольких задач. Что не так с этим кодом?
fn main() {
block_on(speak());
}
async fn speak() {
let hold = vec![say(), greet()];
let results = join_all(hold).await;
}
async fn say() {
println!("hello");
}
async fn greet() {
println!("world");
}
вот вывод компилятора
error[E0308]: mismatched types
--> sync\src\main.rs:14:27
|
14 | let hold = vec![say(),greet()];
| ^^^^^^^ expected opaque type, found a different opaque type
...
23 | async fn greet(){
| - the `Output` of this `async fn`'s found opaque type
|
= note: expected type `impl core::future::future::Future` (opaque type at <sync\src\main.rs:19:15>)
found opaque type `impl core::future::future::Future` (opaque type at <sync\src\main.rs:23:17>)
= note: distinct uses of `impl Trait` result in different opaque types
Ответы
Для двух фьючерсов, как и у вас, используйте future::join
use futures::{executor, future}; // 0.3.5
async fn speak() {
let (_s, _g) = future::join(say(), greet()).await;
}
Есть варианты три, четыре, и пять входных фьючерсов: join3, join4, join5.
Существует также try_join(и try_join3, try_join4, try_join5), когда ваше будущее возвращает Result
.
Макрос join- это еще один способ обработки статического количества фьючерсов, к которым нужно присоединиться.
Если вам нужно поддерживать динамическое количество фьючерсов, вы можете использовать future::join_all(или try_join_all), но у вас должен быть вектор всего одного вида. Проще всего это сделать с помощью FutureExt::boxed(или FutureExt::boxed_local):
use futures::{executor, future, FutureExt}; // 0.3.5
async fn speak() {
let futures = vec![say().boxed(), greet().boxed()];
let _results = future::join_all(futures).await;
}
Обратите внимание, что этот код может запускать фьючерсы одновременно, но не будет запускать их параллельно. Для параллельного выполнения нужно ввести какие-то задачи.
Смотрите также:
- Как я могу присоединиться ко всем фьючерсам в векторе без отмены в случае неудачи, как это делает join_all?
- Присоединяйтесь к фьючерсам с ограниченным параллелизмом
- Как я могу выполнять параллельные асинхронные HTTP-запросы GET с помощью reqwest?
- Как мне создать разнородную коллекцию объектов?
- Какова цель async / await в Rust?
- В чем разница между параллелизмом и параллелизмом?