Empat Jurus Sakti Promise di JavaScript: all, allSettled, race, dan any— Kapan Pakai yang Mana?

⏱ - menit baca

 

perbandingan visual keempat metode kombinator Promise beserta perilaku dan hasilnya

Bagi developer JavaScript yang sering bekerja dengan banyak operasi asynchronous sekaligus — misalnya memanggil beberapa API secara bersamaan — empat metode statis dari Promise ini wajib dikuasai. Meski sekilas mirip, keempatnya punya perilaku yang sangat berbeda saat menangani sukses maupun kegagalan. Salah pilih, bug yang muncul bisa sulit dilacak.

Promise.all(): Semua Harus Berhasil, Tidak Ada Kompromi

Promise.all() adalah yang paling sering dipakai. Ia menunggu semua promise selesai, tapi punya sifat fail-fast — begitu salah satu promise gagal (reject), seluruh operasi langsung dianggap gagal, meski promise lain masih berjalan.

const [user, posts, comments] = await Promise.all([
  fetchUser(id),
  fetchPosts(id),
  fetchComments(id)
]);

Kapan pakai ini? Ketika semua data benar-benar dibutuhkan bersamaan, dan jika salah satu gagal, seluruh proses memang seharusnya gagal juga — misalnya memuat data yang saling bergantung untuk menampilkan satu halaman.

Promise.allSettled(): Semua Ditunggu, Tak Peduli Hasil Akhirnya

Berbeda dari all(), allSettled() selalu menunggu semua promise selesai, tanpa peduli apakah berhasil atau gagal. Hasilnya berupa array objek dengan status fulfilled atau rejected untuk masing-masing promise.

const results = await Promise.allSettled([
  sendEmail(user1),
  sendEmail(user2),
  sendEmail(user3)
]);

results.forEach((r, i) => {
  if (r.status === "fulfilled") {
    console.log(`Email ${i} terkirim:`, r.value);
  } else {
    console.log(`Email ${i} gagal:`, r.reason);
  }
});

Kapan pakai ini? Ketika setiap operasi bersifat independen dan Anda ingin tahu hasil dari semuanya — berhasil atau gagal — tanpa membuat satu kegagalan menghentikan proses lainnya. Cocok untuk kasus seperti mengirim notifikasi ke banyak pengguna sekaligus.

Promise.race(): Siapa Cepat, Dia Menang

Promise.race() menyelesaikan diri begitu satu promise pertama selesai — entah itu berhasil atau gagal. Promise lain yang belum selesai akan tetap berjalan di latar belakang, tapi hasilnya diabaikan.

const result = await Promise.race([
  fetchData(),
  new Promise((_, reject) => 
    setTimeout(() => reject(new Error("Timeout")), 5000)
  )
]);

Kapan pakai ini? Pola paling umum adalah membuat timeout — membandingkan operasi asli dengan promise timeout, sehingga jika operasi terlalu lama, aplikasi tidak menunggu selamanya.

Promise.any(): Cari yang Berhasil Duluan, Abaikan yang Gagal

Promise.any() mirip dengan race(), tapi dengan satu perbedaan penting: ia hanya menyelesaikan diri begitu ada satu promise yang berhasil. Kegagalan dari promise lain diabaikan — kecuali jika semua promise gagal, barulah ia melempar AggregateError.

try {
  const result = await Promise.any([
    fetchFromServerA(),
    fetchFromServerB(),
    fetchFromServerC()
  ]);
  console.log("Berhasil dari salah satu server:", result);
} catch (err) {
  console.log("Semua server gagal:", err.errors);
}

Kapan pakai ini? Ketika Anda punya beberapa sumber data alternatif (misalnya beberapa server cadangan atau CDN) dan cukup butuh satu yang berhasil merespons — tidak peduli yang lain gagal.

Tabel Perbandingan Singkat

Metode Selesai Ketika Fail-fast? Hasil
all() Semua berhasil Ya Array nilai
allSettled() Semua selesai (apa pun hasilnya) Tidak Array status + nilai/alasan
race() Satu selesai duluan Ya (tergantung yang tercepat) Nilai/alasan tercepat
any() Satu berhasil duluan Tidak (kecuali semua gagal) Nilai sukses tercepat

Kesalahan Umum yang Perlu Dihindari

Salah satu jebakan paling sering terjadi adalah memakai Promise.all() padahal sebenarnya butuh allSettled() — akibatnya, satu request gagal bisa membuat seluruh proses batch berhenti total, padahal request lain sebenarnya berhasil dan datanya tetap berharga untuk digunakan.


Memahami perbedaan keempat metode ini bukan sekadar soal sintaksis, tapi soal memilih strategi penanganan error yang tepat untuk skenario nyata. Sebelum menulis Promise.all([...]), ada baiknya bertanya dulu: apakah saya benar-benar butuh semuanya berhasil, atau cukup tahu hasil masing-masing, atau bahkan cukup satu saja yang berhasil?

Ditulis oleh

Inats Studio

πŸ’¬ Komentar ()

Punya pertanyaan atau tanggapan? Yuk diskusi di kolom komentar.

✍ Tulis Komentar