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.
| State | Artinya | Bisa berubah? |
|---|---|---|
| pending | Masih menunggu | Ya, sekali |
| fulfilled | Berhasil, punya value | Tidak, selamanya |
| rejected | Gagal, punya alasan | Tidak, 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.
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.
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.
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.
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
| Combinator | Resolve saat | Reject saat |
|---|---|---|
Promise.all | Semua berhasil | Salah satu gagal — langsung |
Promise.allSettled | Semua selesai, berhasil atau gagal | Tidak pernah |
Promise.race | Yang pertama selesai, apa pun hasilnya | Kalau yang pertama selesai itu gagal |
Promise.any | Yang pertama berhasil | Hanya kalau semuanya gagal |
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 solusiSembunyikan 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));