Memahami Callback dan Promise di jQuery Saat Ambil Data
Categories Tutorial Coding

Memahami Callback dan Promise di jQuery Saat Ambil Data

Callback dan promise di jQuery muncul bersamaan setiap kali kamu memanggil $.ajax. Banyak developer memakai keduanya tanpa tahu persis kapan satu lebih tepat dari yang lain. Akibatnya kode berjalan, tapi susah dibaca dan rawan salah urutan ketika ada dua permintaan yang harus selesai berurutan.

Callback: cara lama yang masih dipakai jQuery

Sejak awal, $.ajax menerima objek berisi fungsi success, error, dan complete. jQuery memanggil fungsi itu ketika permintaan selesai. Pola ini disebut callback karena kamu menyerahkan fungsi yang akan dipanggil balik nanti.

$.ajax({
  url: '/api/produk',
  type: 'GET',
  success: function (data) {
    renderProduk(data);
  },
  error: function (xhr, status, err) {
    tampilkanError(status);
  }
});

Untuk satu permintaan sederhana, callback sudah cukup. Masalah mulai muncul ketika hasil permintaan pertama dibutuhkan untuk permintaan kedua. Kamu menaruh $.ajax di dalam success, lalu permintaan ketiga di dalam success berikutnya. Susunan seperti ini biasa disebut callback hell: kode menjorok ke kanan dan sulit dilacak saat ada error.

Promise di jQuery: objek yang dikembalikan jqXHR

Sejak jQuery 1.5, $.ajax mengembalikan objek jqXHR yang memiliki method .done(), .fail(), dan .always(). Objek ini mengikuti pola promise, jadi kamu bisa merangkai beberapa langkah tanpa bersarang.

$.ajax({ url: '/api/produk' })
  .done(function (data) {
    renderProduk(data);
  })
  .fail(function (xhr) {
    tampilkanError(xhr.status);
  })
  .always(function () {
    sembunyikanLoading();
  });

.done() bisa dirangkai lebih dari sekali. Setiap handler menerima nilai yang sama. Ini berguna kalau kamu ingin memisahkan logika render dari logika pencatatan error, misalnya mengirim kegagalan ke layanan log tanpa mencampurnya dengan kode tampilan.

Merangkai beberapa permintaan dengan then

Method .then() pada jqXHR memungkinkan kamu mengubah hasil sebelum diteruskan ke handler berikutnya. Kalau handler di dalam .then() mengembalikan nilai, nilai itu menjadi masukan bagi .then() selanjutnya. Kalau mengembalikan jqXHR lain, rantai menunggu permintaan itu selesai.

$.ajax({ url: '/api/pesanan/42' })
  .then(function (pesanan) {
    return $.ajax({ url: '/api/pengguna/' + pesanan.userId });
  })
  .then(function (pengguna) {
    tampilkanPemesan(pengguna.nama);
  })
  .fail(function () {
    tampilkanError('Gagal memuat data pesanan');
  });

Rantai di atas menjalankan permintaan kedua hanya setelah yang pertama berhasil. Satu .fail() di ujung menangkap kegagalan dari kedua permintaan. Dengan callback, kamu perlu menulis penanganan error dua kali di tempat berbeda.

Menunggu beberapa permintaan sekaligus

jQuery menyediakan $.when() untuk menggabungkan beberapa jqXHR. Ini berguna ketika halaman butuh data dari dua endpoint sebelum bisa dirender.

$.when(
  $.ajax({ url: '/api/kategori' }),
  $.ajax({ url: '/api/penulis' })
).done(function (resKategori, resPenulis) {
  var kategori = resKategori[0];
  var penulis = resPenulis[0];
  isiForm(kategori, penulis);
});

Setiap argumen di done berupa array berisi data, status teks, dan objek jqXHR. Karena itu kamu perlu mengambil indeks [0] untuk mendapat datanya. Ini salah satu perbedaan jQuery dengan promise bawaan JavaScript modern yang mengembalikan nilai langsung.

Kapan memakai callback, kapan memakai promise

Pilihan ini bergantung pada bentuk alur datamu.

  • Callback cocok untuk satu permintaan tunggal yang hasilnya langsung dipakai. Kode tetap pendek dan mudah dibaca.
  • Promise dipakai ketika ada dua permintaan atau lebih yang saling bergantung, atau ketika penanganan error ingin disatukan di satu tempat.
  • Gunakan $.when() saat beberapa permintaan bisa berjalan paralel dan semuanya harus selesai sebelum render.
  • Hindari mencampur callback dan promise dalam satu alur. Pilih satu gaya agar tidak ada handler yang terlewat.

Kalau kamu sudah terbiasa memilih elemen dengan cara yang tepat, memindahkan logika ke rantai promise akan terasa lebih mudah. Pola cara memilih elemen dengan selector jQuery membantu memastikan handler dipasang pada elemen yang benar sebelum data masuk.

Kesalahan yang sering terjadi

Salah satu jebakan paling umum adalah lupa mengembalikan nilai di dalam .then(). Kalau kamu menulis $.ajax(...) tanpa return, rantai tidak menunggu permintaan itu dan .then() berikutnya menerima undefined.

Jebakan lain adalah menganggap .fail() otomatis menangkap error JavaScript di dalam .done(). Tidak. .fail() hanya menangani kegagalan permintaan HTTP. Kalau fungsi render melempar error, itu harus ditangani terpisah.

Untuk kasus data yang datang dari server dan harus ditampilkan di tabel, alur promise membuat pemisahan tugas lebih jelas: satu fungsi mengambil data, satu fungsi merender. Contoh lengkapnya ada di cara menampilkan data API ke tabel HTML dengan jQuery. Kalau sumber datamu bukan API melainkan basis data di sisi server, lihat juga cara menampilkan data dari database ke HTML dengan PHP sebagai langkah awal sebelum data dikirim ke front-end.

Merapikan kode dengan fungsi pengambil terpisah

Cara paling sederhana menghindari callback hell adalah memecah setiap permintaan menjadi fungsi yang mengembalikan jqXHR. Fungsi-fungsi ini bisa dirangkai di tempat lain tanpa tahu detail URL atau parameter.

function ambilPesanan(id) {
  return $.ajax({ url: '/api/pesanan/' + id });
}

function ambilPengguna(id) {
  return $.ajax({ url: '/api/pengguna/' + id });
}

ambilPesanan(42)
  .then(function (pesanan) {
    return ambilPengguna(pesanan.userId);
  })
  .done(function (pengguna) {
    tampilkanPemesan(pengguna.nama);
  })
  .fail(function () {
    tampilkanError('Data pemesan tidak tersedia');
  });

Dengan pemisahan ini, pengujian jadi lebih mudah karena setiap fungsi punya satu tanggung jawab. Kamu juga bisa memakai ulang ambilPengguna di halaman lain tanpa menyalin kode AJAX.

Ringkasan

Callback di jQuery masih berguna untuk satu permintaan sederhana. Begitu alur data bercabang atau berurutan, promise lewat .done(), .fail(), dan .then() memberi struktur yang lebih mudah dibaca dan dirawat. Pilih satu gaya secara konsisten dan pecah permintaan menjadi fungsi kecil yang bisa dirangkai.

Pertanyaan yang Sering Diajukan

Apakah jqXHR sama dengan Promise bawaan JavaScript?

Mirip, tapi tidak identik. jqXHR punya method .done(), .fail(), dan .always() yang khas jQuery, serta membungkus hasil dalam array saat dipakai dengan $.when(). Promise bawaan JavaScript memakai .then() dan .catch() dengan nilai yang dikembalikan langsung.

Bisakah callback dan promise dipakai bersamaan dalam satu permintaan?

Bisa, karena keduanya berasal dari objek yang sama. Kamu bisa mengisi success di objek pengaturan sekaligus memanggil .done() pada hasilnya. Namun mencampur keduanya membuat alur sulit dilacak, jadi sebaiknya pilih satu.

Apa yang terjadi kalau .then() tidak mengembalikan nilai?

Rantai tetap berjalan, tetapi .then() berikutnya menerima undefined. Kalau di dalamnya ada permintaan AJAX yang tidak di-return, jQuery tidak menunggu permintaan itu selesai sebelum melanjutkan ke langkah berikutnya.

Meja kerja pengembang web dengan laptop menampilkan antarmuka carousel gambar dan sketsa tata letak banner Prev Memilih Plugin jQuery Slider: Perbandingan Tiga Opsi Populer