Promise vs Callback - Memahami Perbedaan dan Manfaatnya dalam JavaScript
Di dalam JavaScript, kita sering menghadapi situasi di mana kita perlu menangani operasi asinkron (asynchronous/async) seperti mengambil data dari server, mengirim email, atau menjalankan fungsi yang membutuhkan waktu lama. Dua pendekatan umum untuk menangani operasi asinkron ini adalah menggunakan callback dan Promise. Dalam artikel ini, kita akan membahas perbedaan antara callback dan Promise, serta kelebihan dan kekurangannya.
Asynchronous adalah proses jalannya program yang dilakukan secara bersamaan tanpa harus menunggu proses antrian. Dengan kata lain, program dapat melanjutkan tugas lainnya tanpa harus menunggu satu tugas selesai sebelum melanjutkan yang lain.
Callback: Pendekatan Klasik
Callback merupakan pendekatan klasik dalam JavaScript untuk menangani operasi asinkron. Dalam pendekatan callback, kita mengirimkan sebuah fungsi sebagai argumen ke fungsi asinkron yang akan dipanggil ketika operasi selesai.
Berikut adalah contoh sederhana penggunaan callback:
function fetchData(callback) {
setTimeout(() => {
const data = "Misalkan ini data dari database";
callback(null, data); // Panggil callback dengan argumen null (tidak ada error) dan data yang diambil
// contoh jika terjadi error
callback(error)
}, 2000);
}
// Panggil fungsi fetchData dengan callback
fetchData((error, data) => {
if (error) {
console.log("Error:", error);
} else {
console.log("Data berhasil diambil:", data);
}
}); Dalam contoh di atas, kita memiliki fungsi fetchData yang mensimulasikan pengambilan data asinkron dengan menggunakan setTimeout. Ketika operasi selesai, kita memanggil callback dengan argumen null (tidak ada error) dan data yang diambil. Callback tersebut kemudian menangani hasil operasi.
Promise: Pendekatan Modern
Promise merupakan pendekatan modern yang diperkenalkan dalam ECMAScript 6 (ES6) untuk menangani operasi asinkron. Promise adalah objek yang merepresentasikan hasil dari operasi yang belum selesai atau belum diketahui pada saat promise dibuat.
Berikut adalah contoh penggunaan Promise:
Membuat Promise
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = "Misalkan ini data dari database";
resolve(data); // Panggil resolve dengan data yang diambil
// Atau, jika terjadi error: reject(new Error("Pesan error"));
}, 2000);
});
} Dalam contoh di atas, kita menggunakan new Promise() untuk membuat Promise. Saat operasi selesai atau sukses, kita panggil fungsi resolve() sehingga status promise menjadi fulfilled. Sebaliknya, kita panggil fungsi reject() untuk menandakan bahwa terjadi error dan status promise akan menjadi rejected.
Mengakses Promise dengan then dan catch
Untuk memanggil promise yang sudah kita buat sebelumnya, dapat menggunakan then dan catch. Lihat contoh berikut:
// Panggil fungsi fetchData dan tangani hasilnya dengan then() dan catch()
fetchData()
.then(data => {
console.log("Data berhasil diambil:", data);
})
.catch(error => {
console.log("Error:", error);
})
.finally(()=>{
// optional
// kode di sini akan berjalan ketika Promise success maupun error
}) Saat promise berstatus fulfilled, maka then akan dipanggil. Sebaliknya, jika status promise rejected, maka catch akan dipanggil. Setelah then maupun catch terpanggil, maka finally akan terpanggil.
Tips:
finallydapat digunakan untuk menjalankan fungsi sesaat setelah promise selesai, entah itu sukses maupun error.
Mengakses Promise dengan async dan await
Terkadang kita ingin mengakses Promise agar berjalan seperti fungsi sinkron. Kita dapat memanfaatkan async dan await. Kita dapat mengubah kode sebelumnya menjadi seperti berikut:
async function(){
try {
const data = await fetchData()
console.log("Data berhasil diambil:", data);
} catch(error){
console.log("Error:", error);
} finally(){ //optional
}
} Harap diperhatikan bahwa saat menggunakan async dan await, kita diharapkan untuk membungkus kode dengan try catch agar error dapat dihandle. Kelebihan menggunakan async dan await adalah kode yang kita tulis menjadi lebih rapih.
Catatan:
awaithanya bisa dijalankan di dalam fungsi yang berbentukasync. Dalam ES Module, terdapat fitur top level await di mana kita dapat menggunakanawaitdiluar fungsi.
Perbandingan Callback dan Promise
Berikut adalah beberapa perbedaan dan manfaat yang dimiliki oleh callback dan Promise:
1. Keterbacaan Kode: Promise memberikan kode yang lebih mudah dibaca dan dipahami karena menggunakan metode berantai (then()) untuk menangani hasil, sehingga mengurangi callback hell (nested callbacks) yang sulit dibaca.
2. Error Handling: Dalam Promise, kita dapat menggunakan .catch() untuk menangani semua jenis error yang terjadi dalam rantai operasi. Dalam callback, kita harus menulis callback error secara manual di setiap level operasi.
3. Penanganan Multiple Async: Promise memungkinkan kita untuk menangani beberapa operasi asinkron secara bersamaan dengan menggunakan metode Promise.all() atau Promise.race(). Kita akan bahas metode ini di artikel yang akan datang. Callback tidak memiliki mekanisme bawaan untuk menangani kasus-kasus ini.
4. Return Value: Promise mengembalikan nilai yang dapat digunakan kembali, sehingga memudahkan dalam penggunaan nilai hasil operasi dalam kode selanjutnya. Callback tidak secara eksplisit mengembalikan nilai.
Kesimpulan
Callback dan Promise adalah dua pendekatan yang umum digunakan dalam JavaScript untuk menangani operasi asinkron. Promise memiliki manfaat tambahan seperti kode yang lebih mudah dibaca, penanganan error yang lebih baik, dan kemampuan untuk menangani multiple operasi asinkron secara bersamaan. Namun, callback masih relevan dalam beberapa kasus khusus dan dalam lingkungan yang tidak mendukung Promise. Pilihan antara callback dan Promise tergantung pada kebutuhan dan preferensi pengembang.
