CodeBlanks Logo Icon CodeBlanks

await

.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

main.rs
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

main.rs
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

Soru
async fn toplam() -> u32 {
    let a = fiyat(1).____;
    a
}
Cevap
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

İleri seviye bölümündeki tüm dersler