0Pricing
Learn Rust Coding · Pelajaran

Bekerja dengan Future dan Tugas

Pahami trait `Future` serta cara tugas dijadwalkan dan dikelola dalam lingkungan runtime asinkron.

Bekerja dengan Future dan Tugas adalah pelajaran Learn Rust Coding gratis di CoddyKit. Ini adalah pelajaran 3 dari 3. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Learn Rust Coding, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Learn Rust Coding mencakup 3 pelajaran total.

Apa Itu Future Rust?

Dalam Rust asinkron, Future adalah trait yang merepresentasikan komputasi asinkron yang mungkin selesai pada suatu waktu. Anggaplah ini sebagai janji untuk suatu nilai yang belum siap.

  • Ini adalah blok pembangun inti untuk Rust async.
  • Fungsi async fn di Rust sebenarnya mengembalikan tipe anonim yang mengimplementasikan trait Future.
  • Nilainya tidak dihitung segera; nilai tersebut dihitung ketika Future "dipoll" oleh pelaksana.

Cara Future Mengalami Kemajuan

Sebuah Future tidak berjalan dengan sendirinya. Pelaksana (seperti runtime Tokio) berulang kali melakukan "poll" terhadapnya untuk memeriksa apakah prosesnya mengalami kemajuan atau telah selesai.

  • Saat dilakukan poll, sebuah Future mengembalikan Poll::Pending (belum selesai) atau Poll::Ready(T) (selesai, berikut hasilnya).
  • Jika hasilnya Pending, pelaksana akan mengetahui bahwa Future perlu dipoll lagi nanti ketika sesuatu yang relevan terjadi (misalnya, I/O selesai).
  • Mekanisme polling ini memungkinkan banyak operasi asinkron berjalan secara bersamaan pada satu thread.

Kode Async Anda adalah Future

Saat Anda menulis async fn, Rust mengubahnya menjadi mesin status yang mengimplementasikan trait Future. Komputasi sebenarnya baru dimulai ketika Future yang dikembalikan dipoll.

Mari kita lihat fungsi async sederhana. Fungsi ini tidak berjalan sampai ditunggu oleh pelaksana.

async fn say_hello() -> String {
    "Hello from a Future!".to_string()
}

#[tokio::main]
async fn main() {
    let future = say_hello(); // This doesn't run the function yet!
    println!("Future created, but not awaited.");
    // To run it, an executor needs to poll it, often via .await
    // let result = future.await;
    // println!("{}", result);
}

Future Menjadi Tugas

Jika Future merupakan definisi dari komputasi async, tugas adalah instans aktif dari Future tersebut yang diarahkan hingga selesai oleh pelaksana.

  • Ketika Anda meminta pelaksana (seperti Tokio) menjalankan sebuah Future, pelaksana tersebut membungkusnya dalam sebuah tugas.
  • Pelaksana kemudian mengelola tugas ini dan melakukan polling setiap kali tugas siap mengalami kemajuan.
  • Tugas adalah unit pekerjaan yang dijadwalkan dan dijalankan secara bersamaan oleh runtime async.

Membuat Tugas untuk Konkurensi

Untuk menjalankan sebuah Future secara bersamaan dengan kode lain, Anda dapat melakukan "spawn" pada runtime Tokio. Tindakan ini membuat tugas baru yang akan dikelola oleh runtime.

Fungsi tokio::spawn menerima sebuah Future dan mengembalikan JoinHandle, yang dapat Anda gunakan untuk menunggu tugas selesai dan mendapatkan hasilnya.

async fn perform_task(id: u8) -> String {
    tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
    format!("Task {} finished!", id)
}

#[tokio::main]
async fn main() {
    println!("Main started.");
    let handle = tokio::spawn(async {
        perform_task(1).await
    });
    println!("Task 1 spawned.");
    // We will await 'handle' in the next scene to get the result.
    // let result = handle.await.unwrap();
    // println!("{}", result);
}

Mendapatkan Hasil dari Tugas

JoinHandle yang dikembalikan oleh tokio::spawn itu sendiri merupakan sebuah Future. Anda dapat melakukan .await pada handle ini untuk menunggu tugas yang dibuat selesai dan mengambil nilai yang dikembalikannya.

Jika tugas yang dibuat mengalami panic, melakukan await pada JoinHandle akan mengembalikan error.

async fn perform_task(id: u8) -> String {
    tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
    format!("Task {} finished!", id)
}

#[tokio::main]
async fn main() {
    println!("Main started.");
    let handle = tokio::spawn(async {
        perform_task(1).await
    });
    println!("Task 1 spawned.");
    let result = handle.await.unwrap(); // Await the handle to get the result
    println!("{}", result);
    println!("Main finished.");
}

Beberapa Tugas Bersamaan

Kekuatan tugas dan tokio::spawn benar-benar terlihat saat Anda menjalankan beberapa operasi secara bersamaan. Runtime Tokio secara efisien berpindah antar tugas saat tugas-tugas tersebut siap.

Hal ini memungkinkan program Anda mengalami kemajuan dalam banyak hal sekaligus tanpa terhambat, bahkan pada satu thread.

async fn long_task(id: u8) -> String {
    tokio::time::sleep(tokio::time::Duration::from_millis(100 + id as u64 * 50)).await;
    format!("Long task {} done!", id)
}

#[tokio::main]
async fn main() {
    println!("Main started.");
    let handle1 = tokio::spawn(long_task(1));
    let handle2 = tokio::spawn(long_task(2));
    println!("Both tasks spawned.");
    let result1 = handle1.await.unwrap();
    let result2 = handle2.await.unwrap();
    println!("{}\n{}", result1, result2);
    println!("Main finished.");
}

Menunggu Semuanya dengan join!

Ketika Anda perlu menunggu beberapa Future selesai pada saat yang sama, tokio::join! adalah makro yang berguna. Makro ini menunggu semua future yang diberikan secara bersamaan dan mengembalikan hasilnya sebagai tuple.

Fungsinya mirip dengan melakukan await pada setiap handle secara terpisah, tetapi biasanya lebih ringkas untuk jumlah future yang tetap.

async fn fetch_data(source: &str) -> String {
    tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
    format!("Data from {}", source)
}

#[tokio::main]
async fn main() {
    println!("Starting data fetches...");
    let (data_a, data_b) = tokio::join!(
        fetch_data("Server A"),
        fetch_data("Database B")
    );
    println!("Fetched: {}\nFetched: {}", data_a, data_b);
    println!("All fetches complete.");
}

Menangani Error Tugas

Operasi asinkron dapat gagal, sama seperti operasi sinkron. Future sering kali mengembalikan tipe Result yang menunjukkan keberhasilan atau kegagalan.

Saat melakukan await pada JoinHandle, ingat bahwa hasilnya dibungkus dalam Result lain karena tugas itu sendiri mungkin mengalami panic. Anda akan sering melihat handle.await? (jika berada dalam async fn yang mengembalikan Result) atau handle.await.unwrap() / .expect().

async fn might_fail(should_fail: bool) -> Result<String, &'static str> {
    tokio::time::sleep(tokio::time::Duration::from_millis(30)).await;
    if should_fail {
        Err("Oops, something went wrong!")
    } else {
        Ok("Operation successful!".to_string())
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let handle_ok = tokio::spawn(might_fail(false));
    let handle_err = tokio::spawn(might_fail(true));

    let result_ok = handle_ok.await??; // Await handle, then await inner Result
    println!("{}", result_ok);

    match handle_err.await? { // Await handle, then handle inner Result
        Ok(val) => println!("{}", val),
        Err(e) => eprintln!("Error: {}", e),
    }
    Ok(())
}

Memahami Future dan Tugas

Anda telah mempelajari Future sebagai komputasi dan Tugas sebagai instans pelaksanaannya. Pernyataan mana tentang tokio::spawn dan JoinHandle yang benar?

Ringkasan: Future dan Tugas

Kerja bagus! Kini Anda telah memahami konsep inti Future dan tugas dalam ekosistem asinkron Rust:

  • Sebuah Future adalah trait yang merepresentasikan komputasi asinkron yang pada akhirnya menghasilkan suatu nilai.
  • async fn dikompilasi menjadi tipe yang mengimplementasikan trait Future.
  • Tugas adalah instans dari Future yang secara aktif dikelola dan dipoll oleh pelaksana (seperti Tokio).
  • tokio::spawn digunakan untuk membuat tugas baru dan mengembalikan JoinHandle.
  • Anda melakukan .await pada JoinHandle untuk mendapatkan hasil dari tugas yang dibuat.

Blok pembangun ini penting untuk menulis aplikasi Rust yang efisien dan tidak menghambat!

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Bekerja dengan Future dan Tugas” gratis?

Ya — teks lengkap “Bekerja dengan Future dan Tugas” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Learn Rust Coding, upgrade ke CoddyKit PRO. Kursus Learn Rust Coding mencakup 3 pelajaran total.

Apa yang akan aku pelajari di “Bekerja dengan Future dan Tugas”?

Pahami trait `Future` serta cara tugas dijadwalkan dan dikelola dalam lingkungan runtime asinkron. Kamu berlatih Learn Rust Coding dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Learn Rust Coding?

Tidak diperlukan pengalaman sebelumnya. Learn Rust Coding di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 3.

Berapa lama pelajaran “Bekerja dengan Future dan Tugas” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Learn Rust Coding ini?

Ya. Setiap pelajaran Learn Rust Coding menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Pengantar Async/Await
  2. Membangun Aplikasi Asinkron dengan Tokio
  3. Bekerja dengan Future dan Tugas
← Kembali ke Learn Rust Coding