Masalah promise hell dalam JavaScript
Anda sudah tahu bahwa promise dibuat untuk memecahkan masalah callback hell. Namun, seiring waktu ternyata promise juga dapat menghasilkan kode yang rumit. Masalah ini secara analogi disebut promise hell.
Mari kita bahas masalah ini dengan contoh
kode. Misalkan kita memiliki fungsi getSmth,
yang menerima parameter dan mengembalikan hasil
tergantung pada parameter tersebut:
function getSmth(num) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(num * num), 1000)
});
}
Dalam kasus ini kita mengimitasi operasi yang berguna (misalnya, mengambil data dari server). Sebagai imitasi kita hanya meneruskan angka sebagai parameter dan setelah satu detik mengembalikan kuadrat dari angka tersebut.
Sekarang mari kita gunakan fungsi kita
getSmth di dalam fungsi lain:
function func() {
getSmth(2).then(res => {
console.log(res); // akan menampilkan 4
});
}
func();
Masalah pertama
Banyaknya konstruksi then yang berurutan
membuat kode sulit dipahami:
function func(){
getSmth(2).then(res1 => {
// lakukan sesuatu
}).then(res2 => {
// lakukan sesuatu
}).then(res3 => {
// lakukan sesuatu
}).then(res4 => {
// lakukan sesuatu
}).then(res5 => {
// lakukan sesuatu
}).then(res6 => {
// lakukan sesuatu
});
}
func();
Masalah kedua
Ada masalah lain. Misalkan sekarang kita ingin menggunakan fungsi kita dua kali, lalu menjumlahkan hasilnya. Hasilnya kita akan mendapatkan kode seperti ini:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
console.log(res1 + res2); // akan menampilkan 13
});
});
}
func();
Sudah mengingatkan pada callback hell, bukan? Mari tambahkan satu lagi pemanggilan fungsi - kodenya akan menjadi lebih buruk lagi:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();
Tentu saja, kita bisa menggunakan Promise.all:
function func() {
Promise.all([getSmth(2), getSmth(3), getSmth(4)]).then(res => {
console.log(res[0] + res[1] + res[2]);
});
}
func();
Tetapi, apakah kita mendapatkan hal yang sama? Tidak! Dalam kasus pertama, setiap fungsi baru menunggu penyelesaian promise sebelumnya, sedangkan dalam kasus kedua - semua promise dieksekusi secara bersamaan. Perbedaan ini akan signifikan ketika kita ingin meneruskan hasil pemanggilan fungsi sebelumnya ke fungsi berikutnya:
function func() {
getSmth(2).then(res1 => {
getSmth(res1).then(res2 => {
getSmth(res2).then(res3 => {
console.log(res3);
});
});
});
}
func();