Ini episode yang paling sering bikin pemula menyerah di tengah jalan, padahal konsepnya sederhana kalau dijelaskan dengan analogi yang tepat. Setelah episode #47 soal module dan NPM, sekarang kita bahas async JavaScript: Promise dan async await.
Kenapa topik ini wajib? Karena hampir semua hal menarik di web itu butuh waktu: mengambil data dari server, membaca file, menunggu user. Kalau JavaScript berhenti total setiap kali menunggu, websitemu akan macet (freeze) setiap ada loading. Async adalah solusi JavaScript supaya program tetap responsif sambil menunggu.
Analoginya: Pesan Makanan di Warteg
Bayangkan kamu pesan makanan di warteg yang ramai. Ada dua cara melayani:
Cara sinkron (blocking): kamu pesan, lalu berdiri mematung di depan kasir sampai makananmu jadi. Antrian di belakangmu menunggu. Semua orang diam. Tidak efisien, kan?
Cara asinkron (non-blocking): kamu pesan, dapat nomor antrean, lalu duduk santai main HP. Saat makanan jadi, nomor kamu dipanggil. Selama menunggu, kasir melayani pelanggan lain. Semua orang tetap bergerak.
JavaScript bekerja dengan cara kedua. Saat kamu meminta data dari server, JavaScript tidak mematung menunggu. Ia memberimu sebuah Promise (ibarat nomor antrean: janji bahwa hasilnya akan datang), lalu melanjutkan kerjaan lain. Saat datanya tiba, kode yang menunggu janji itu dijalankan.
Promise punya tiga status, persis seperti nomor antreanmu:
- pending: masih menunggu, makanan belum jadi.
- fulfilled: berhasil, makanan datang. Nilainya bisa dipakai lewat
.then(). - rejected: gagal, misalnya bahan habis. Errornya ditangkap lewat
.catch().
// Simulasi janji yang butuh 2 detik
function masakMie() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const mieHabis = false;
if (mieHabis) {
reject("Maaf, mie habis!");
} else {
resolve("Mie goreng spesial sudah jadi!");
}
}, 2000);
});
}
masakMie()
.then(pesan => console.log(pesan)) // kalau berhasil
.catch(err => console.log(err)); // kalau gagal
console.log("Sambil menunggu, aku bisa ngobrol dulu.");
Berhenti dan tebak dulu! Urutan apa yang tercetak di console dari kode di atas?
Callback Hell dan Kenapa Kita Butuh yang Lebih Baik
Sebelum Promise populer, programmer memakai callback: function yang dilempar sebagai argumen untuk dijalankan nanti. Masalahnya, kalau ada 4-5 langkah berurutan (login, ambil profil, ambil postingan, ambil komentar), kodenya menjorok ke dalam seperti piramida. Ini dijuluki callback hell atau "piramida kutukan".
Promise memperbaikinya dengan chaining: tiap .then() mengembalikan Promise baru, jadi bisa disambung ke bawah, bukan ke dalam. Tapi masih terasa seperti rantai yang panjang. Maka lahirlah async await: cara menulis kode async yang terlihat seperti kode biasa dari atas ke bawah.
// Dengan async/await: terlihat seperti kode sinkron biasa
async function pesanMakanan() {
try {
const mie = await masakMie(); // tunggu sampai jadi
console.log(mie);
const minum = await buatkanTeh(); // baru lanjut ke langkah berikut
console.log(minum);
} catch (err) {
console.log("Gagal pesan:", err); // semua error ditangkap di sini
}
}
Tiga aturan main async await yang wajib dihafal:
awaithanya boleh dipakai di dalam functionasync. Ini aturan keras bahasa.awaitmenjeda function itu saja, bukan seluruh program. Kode lain di luar function tetap jalan. Ini bedanya dengan "freeze".- Function
asyncselalu mengembalikan Promise, walaupun kamu me-return nilai biasa. Jadi pemanggilnya tetap perluawaitatau.then().
Berhenti dan tebak dulu! Apa output kode ini?
async function dapatAngka() {
return 42;
}
const hasil = dapatAngka();
console.log(hasil);
Kuis cepat: Manakah pernyataan yang BENAR tentang async await?
Persepsi yang Perlu Diluruskan
Persepsi salah 1: "Pakai async await berarti kodenya jadi sinkron dan blocking." Salah total. await hanya menjeda function itu, program lain tetap jalan. Buktinya ada di Tebak Dulu pertama tadi: baris di luar function tetap dieksekusi duluan.
Persepsi salah 2: "Error di kode async tidak perlu ditangani khusus." Justru sebaliknya. Promise yang rejected tapi tidak ada .catch() atau try catch akan jadi error misterius yang sulit dilacak. Biasakan selalu pasang penangkap error, seperti pramusaji yang selalu siap kalau pesanan gagal.
Latihan: Simulasi Dapur Asinkron
Tulis program kecil yang mensimulasikan tiga pesanan warteg dengan waktu masak berbeda (pakai setTimeout dalam Promise, misalnya 1 detik, 2 detik, 3 detik). Lalu:
- Jalankan ketiganya berurutan dengan
awaitsatu per satu, catat total waktunya (harusnya sekitar 6 detik). - Ubah kodenya supaya ketiganya dimasak bersamaan memakai
Promise.all([pesan1, pesan2, pesan3]). Catat total waktunya sekarang (harusnya sekitar 3 detik, mengikuti yang paling lama). - Renungkan: kapan harus berurutan dan kapan boleh bersamaan? (Petunjuk: kalau langkah B butuh hasil langkah A, wajib berurutan.)
Latihan ini melatih intuisi terpenting programmer async: membedakan yang harus antre dan yang boleh paralel. Di episode berikutnya, kita pakai semua ilmu ini untuk proyek nyata: Fetch API dan Aplikasi Cuaca, aplikasi pertamamu yang mengambil data sungguhan dari internet. Sampai jumpa.
Diskusi & Komentar 0
Punya tanggapan, pertanyaan, atau tips seputar tutorial ini? Tulis komentar kamu di bawah!
Jadilah yang pertama membuka obrolan dan berbagi pandangan seputar tutorial resep kode ini.
Tulis Komentar
Komentar menggunakan akun Google. Harap berkomentar dengan santun dan berbobot.