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:

javascriptfunction 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:

javascriptfunction func() {
  getSmth(2).then(res => {
    console.log(res); // akan menampilkan 4
  });
}

func();

Masalah pertama

Banyaknya konstruksi then yang berurutan membuat kode sulit dipahami:

javascriptfunction 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:

javascriptfunction 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:

javascriptfunction 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:

javascriptfunction 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:

javascriptfunction func() {
  getSmth(2).then(res1 => {
    getSmth(res1).then(res2 => {
      getSmth(res2).then(res3 => {
        console.log(res3);
      });
    });
  });
}

func();