Lompat ke konten
Kembali ke modul

Cara JavaScript Berjalan: Engine, Event Loop, Async · 6/9

Promise

Sebuah object yang mewakili nilai yang belum kamu punya. State, chaining, dan cara menggabungkannya.

Baca 32 menit

Setelah pelajaran ini kamu bisa

  • Menjelaskan apa itu promise dan tiga state yang mungkin dimilikinya
  • Merangkai promise sehingga setiap langkah memberi hasil ke langkah berikutnya
  • Menangani rejection, dan menjelaskan ke mana error berjalan
  • Memilih antara `all`, `allSettled`, `race`, dan `any`

Promise adalah object yang mewakili value yang belum kamu punya. Ini jawaban atas masalah dari pelajaran sebelumnya: kamu tidak bisa mengembalikan value yang belum datang, tapi kamu *bisa* mengembalikan object yang berjanji akan menyimpannya nanti.

StateArtinyaBisa berubah?
pendingMasih menungguYa, sekali
fulfilledBerhasil, punya valueTidak, selamanya
rejectedGagal, punya alasanTidak, selamanya

"Selesai sekali, lalu tidak berubah lagi" adalah sifat yang mematikan bug callback ganda dari pelajaran sebelumnya. Memanggil resolve dua kali bukan error — pemanggilan kedua sekadar diabaikan.

Coba sendiri

Hasil

Tekan Jalankan untuk melihat hasilnya.

Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.

Chaining

.then() mengembalikan promise baru, dan itulah yang membuat chaining bekerja. Apa pun yang kamu return dari dalam sebuah then jadi value untuk then berikutnya — dan kalau kamu me-return sebuah promise, rantainya akan menunggunya.

Coba sendiri

Hasil

Tekan Jalankan untuk melihat hasilnya.

Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.

Coba sendiri

Hasil

Tekan Jalankan untuk melihat hasilnya.

Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.

Error berjalan turun di rantainya

Sebuah rejection melewati setiap then sampai menemukan sebuah catch. Artinya satu catch di akhir mencakup semua langkah di atasnya — perbaikan besar dibanding mengulang if (error) di setiap tingkat.

Coba sendiri

Hasil

Tekan Jalankan untuk melihat hasilnya.

Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.

Menjalankan beberapa sekaligus

CombinatorResolve saatReject saat
Promise.allSemua berhasilSalah satu gagal — langsung
Promise.allSettledSemua selesai, berhasil atau gagalTidak pernah
Promise.raceYang pertama selesai, apa pun hasilnyaKalau yang pertama selesai itu gagal
Promise.anyYang pertama berhasilHanya kalau semuanya gagal
Coba sendiri

Hasil

Tekan Jalankan untuk melihat hasilnya.

Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.

Tugas praktik

Tulis withTimeout(promise, ms) yang resolve dengan value promise-nya kalau selesai tepat waktu, dan reject dengan Error("timed out") kalau tidak. Pakai Promise.race. Uji terhadap promise yang butuh 10ms dan yang butuh 100ms, dengan batas 30ms.

Hasil yang diharapkan

Yang cepat resolve; yang lambat reject dengan "timed out".

Tampilkan contoh solusi

Coba dulu minimal sepuluh menit sebelum membuka ini. Bagian yang terasa susah itu justru yang mengajari kamu.

function withTimeout(promise, ms) {
  const timeout = new Promise((_, reject) => {
    setTimeout(() => reject(new Error("timed out")), ms);
  });
  return Promise.race([promise, timeout]);
}

function slow(value, ms) {
  return new Promise((resolve) => setTimeout(() => resolve(value), ms));
}

withTimeout(slow("quick", 10), 30)
  .then((v) => console.log("resolved:", v))
  .catch((e) => console.log("rejected:", e.message));

withTimeout(slow("sluggish", 100), 30)
  .then((v) => console.log("resolved:", v))
  .catch((e) => console.log("rejected:", e.message));