Zum Inhalt springen

Futures

Gegeben ist eine Funktion sleep(d), die für die angegebene Dauer pausiert. Betrachten Sie die folgende Funktion:

let futs: Vec<_> = [1, 2, 3].iter().map(|n| async move {
sleep(Duration::from_secs(5)).await;
n + 1
}).collect();
for fut in futs {
let n = fut.await;
println!("{n}");
}

Wenn dieser Code ausgeführt wird, wie viele Sekunden sollte die Ausführung ungefähr dauern?

Ohne die Verwendung einer Funktion wie join_all werden die Futures nicht gleichzeitig ausgeführt. Daher würde dieser Code 15 Sekunden dauern (5 Sekunden pro Listenelement).


Angenommen, Sie entwerfen eine Hilfsfunktion mit der folgenden Spezifikation:

map_stringify nimmt zwei Argumente entgegen: einen Vektor von Eingaben und eine asynchrone Funktion, die die Eingabe in eine Ausgabe umwandelt, wobei die Ausgaben in Strings umgewandelt werden können. map_stringify gibt einen Vektor von in Strings umgewandelten Ausgaben zurück.

Welche Funktionstyp-Signatur kodiert diese Spezifikation am besten?

Hier ist eine Implementierung der angegebenen Funktion:

async fn map_stringify<I, O, F>(
f: impl Fn(I) -> F, inputs: Vec<I>
) -> Vec<String>
where
O: ToString,
F: Future<Output = O>,
{
let f = &f;
let futs = inputs
.into_iter()
.map(|input| async move { f(input).await.to_string() });
futures::future::join_all(futs).await
}

Angenommen, Sie schreiben ein Programm, das asynchronen Code ausführen muss, aber alle 500 ms prüfen soll, ob die Berechnung angehalten werden muss. Welche Hilfsfunktion wäre am besten geeignet, um diese Aufgabe zu erfüllen?

Sie könnten beispielsweise eine select-Anweisung in einer Schleife zwischen einem langlaufenden Future und einem Sleep-Future ausführen, der in 500 ms abgeschlossen wird.