await
- Rust kursu
- İleri seviye
- Ders 2/81
- 4 dk
.await ile bir future'ı beklemeyi öğrenirsin.
await
.await, bir Future'ın tamamlanmasını bekler ve sonucunu verir. Yalnızca async bağlamda kullanılabilir. Bekleme sırasında iş parçacığı bloke olmaz: runtime aynı iş parçacığında başka görevleri çalıştırabilir:
async fn fiyat(id: u32) -> u32 {
id * 10 // gerçekte: veritabanı sorgusu
}
async fn toplam() -> u32 {
let a = fiyat(1).await;
let b = fiyat(2).await;
a + b
}Burada iki çağrı sırayla çalışır. Eşzamanlı çalıştırmak için join! gibi araçlar gerekir.
await bir duraklama noktasıdır
Derleyici async fonksiyonu bir durum makinesine çevirir; her .await bir durumdur. Future henüz hazır değilse fonksiyon o noktada duraklar ve yerel değişkenleri durum makinesinin içinde saklanır. Bu yüzden async fonksiyonlarda stack yerine Future'ın kendisi değişkenleri taşır.
// kavramsal olarak:
enum Toplam {
Basla,
BirinciBekliyor { f: FiyatFuture },
IkinciBekliyor { a: u32, f: FiyatFuture },
Bitti,
}Uygulama Zincirli await
Yukarıdaki fiyat ve toplam async fonksiyonlarını yaz. block_on ile toplam() sonucunu yazdır.
Başlangıç kodu
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, Waker};
fn block_on<F: Future>(f: F) -> F::Output {
let mut f = pin!(f);
let mut cx = Context::from_waker(Waker::noop());
loop {
if let Poll::Ready(v) = f.as_mut().poll(&mut cx) {
return v;
}
}
}
fn main() {
// buraya yaz
}Örnek çözüm
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, Waker};
fn block_on<F: Future>(f: F) -> F::Output {
let mut f = pin!(f);
let mut cx = Context::from_waker(Waker::noop());
loop {
if let Poll::Ready(v) = f.as_mut().poll(&mut cx) {
return v;
}
}
}
async fn fiyat(id: u32) -> u32 {
id * 10
}
async fn toplam() -> u32 {
let a = fiyat(1).await;
let b = fiyat(2).await;
a + b
}
fn main() {
println!("{}", block_on(toplam()));
}Beklenen çıktı
30
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Normal (async olmayan) bir fonksiyonda <code>.await</code> yazılırsa ne olur?
- E0728: await yalnızca async fonksiyon ve bloklarda Doğru cevap
- Çalışır
- Thread bloke olur
- Uyarı verir
Açıklama: Senkron koddan bir Future'ı çalıştırmak için bir yürütücünün block_on gibi bir giriş noktası kullanılır.
2 Sonucu bekle
async fn toplam() -> u32 {
let a = fiyat(1).____;
a
}
async fn toplam() -> u32 {
let a = fiyat(1).await;
a
}
Açıklama: .await Future'ın sonucunu verir.
3 İfade ve türü
| Kavram | Anlamı |
|---|---|
fiyat(1) |
impl Future<Output = u32> |
fiyat(1).await |
u32 |
toplam() |
Henüz çalışmamış Future |
block_on(toplam()) |
30 |