await in Rust
In diesem Artikel lernen wir die Bedeutung von warten
in Rust kennen.
await
in Rust
async-await
ist eine Technik zum Schreiben von Funktionen, die anhalten, die Kontrolle an die Laufzeit übergeben und dann die Ausführung dort fortsetzen können, wo sie aufgehört haben. Normalerweise werden diese Pausen verwendet, um auf E/A zu warten, aber sie können verschiedenen Zwecken dienen.
async-await
ist Ihnen vielleicht von JavaScript oder C# bekannt. Die Implementierung der Funktionalität in Rust weist jedoch einige wichtige Änderungen auf.
Um async-await
zu nutzen, müssen Sie fn
durch async fn
ersetzen:
async fn new_fxn() -> u32 { .. }
Im Gegensatz zu einer herkömmlichen Funktion hat der Aufruf eines async fn
keine unmittelbare Wirkung. Stattdessen gibt es eine future
zurück.
Die Berechnung wird ausgesetzt und wartet darauf, ausgeführt zu werden. Verwenden Sie den .await
-Operator, um das future
auszuführen:
async fn second_fxn () {
let future = new_fxn();
let result: u32 = future.await;
...
}
Dieses Beispiel verdeutlicht den ersten Unterschied zwischen Rust und anderen Sprachen: Wir schreiben future.await
statt await future. Diese Syntax interagiert besser mit Rusts ?
Operator zum Propagieren von Fehlern, die bei der E/A üblich sind.
Sie können future.await?
schreiben. Fehler zu tragen und das Ergebnis von vielem abzuwarten. Zusätzlich hat es den Vorteil, dass die Methode des Verkettens schmerzlos wird.
Der Begriff await
kann nur im Zusammenhang mit asynchronen Funktionen verwendet werden, und nur auf asynchrone Funktionen kann gewartet werden.
Rusts future
sind lax; Standardmäßig werden sie nichts tun, bevor die erste Umfrage durchgeführt wird. Wenn man await
die future
, wird sie abgefragt.
Rufen Sie beispielsweise eine Funktion auf, die am Anfang Ihres Programms ein future
zurückgibt, aber erst am Ende des Programms darauf await
, wird die eigentliche Anfrage erst ausgeführt, wenn Sie darauf await
.
Beispiel:
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;
}
Zunächst werden fünf futures
(fünf async
-Blöcke) erstellt, wobei jede future
eine sleep
-Future erstellt und darauf await
aufruft. Diese futures
existieren gleichzeitig.
Jeder Block zeigt die Thread-ID vor und nach await
an.
Ausgabe:
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))