await à Rust
Dans cet article, nous allons apprendre la signification de await
en Rust.
await
en Rust
async-await
est une technique d’écriture de fonctions qui peuvent faire une pause, céder le contrôle à l’exécution, puis reprendre l’exécution là où elles se sont arrêtées. En règle générale, ces pauses sont utilisées pour attendre les E/S, mais elles peuvent servir à diverses fins.
async-await
peut vous être familier avec JavaScript ou C#. Cependant, l’implémentation de la fonctionnalité par Rust comporte quelques changements importants.
Pour utiliser async-wait
, vous devez remplacer fn
par async fn
:
async fn new_fxn() -> u32 { .. }
Contrairement à une fonction classique, l’appel d’un async fn
n’a pas d’effet immédiat. Il renvoie un future
à la place.
Le calcul est suspendu et attend d’être exécuté. Utilisez l’opérateur .await
pour exécuter le future
:
async fn second_fxn () {
let future = new_fxn();
let result: u32 = future.await;
...
}
Cet exemple illustre la première distinction entre Rust et les autres langages : on écrit future.await
plutôt qu’attend futur. Cette syntaxe interagit mieux avec le ?
de Rust opérateur pour propager les erreurs, qui sont courantes dans les E/S.
Vous pouvez écrire future.await?
pour supporter des fautes et attendre le résultat de beaucoup. De plus, il a l’avantage de rendre la méthode d’enchaînement indolore.
Le terme await
ne peut être utilisé que dans le contexte de fonctions asynchrones, et seules les fonctions asynchrones peuvent être attendues.
Les futures
de Rust sont laxistes ; par défaut, elles ne feront rien avant que le premier poll soit effectué. Lorsque vous attendez
le future
, il est sondé.
Par exemple, si vous appelez une fonction qui renvoie un future
au début de votre programme mais que vous ne le await
pas avant la fin du programme, la requête réelle ne sera pas exécutée avant que vous ne le await
.
Exemple:
use std::thread;
use tokio::time::{sleep, Duration};
use futures::future;
#[tokio::main]
async fn main(){
let mut await_demo = Vec::new();
for count in 1..=5
{
await_demo.push(tokio::spawn(async move{
println!("Start the thread {count}, id= {:?}", thread::current().id());
sleep (Duration::from_millis(5000)).await;
println!("end the thread {count}, id = {:?})", thread::current().id());
}));
}
future::join_all (await_demo).await;
}
Tout d’abord, cinq futures
(cinq blocs async
) sont créés, chaque future
créant un futur sleep
et appelant await
sur celui-ci. Ces futures
existent de manière concurrente.
Chaque bloc affiche l’identifiant du thread avant et après await
.
Production:
Standard Output
Start the thread 1, id= ThreadId(2)
Start the thread 3, id= ThreadId(2)
Start the thread 4, id= ThreadId(2)
Start the thread 5, id= ThreadId(2)
Start the thread 2, id= ThreadId(3)
end the thread 2, id = ThreadId(2))
end the thread 3, id = ThreadId(3))
end the thread 1, id = ThreadId(3))
end the thread 4, id = ThreadId(3))
end the thread 5, id = ThreadId(3))