Callback adalah fungsi yang kamu kirim ke fungsi lain sebagai argumen, lalu fungsi penerimanya yang memanggil. Kamu sendiri gak memanggilnya. Mirip nitip pesan: "kalau sudah selesai, kabari aku".
🧪 Tebakan cepat: ada
setTimeout1 detik di tengah kode. Apa baris di bawahnya menunggu dulu sampai 1 detik itu habis? Tebak dulu, jawabannya ada di bagian "Callback yang dipanggil nanti".
Fungsi yang dikirim ke fungsi lain
console.log("mulai");
const numbers = [1, 2, 3];
numbers.forEach((n) => {
console.log("callback:", n);
});
console.log("selesai");
Yang tercetak:
mulai
callback: 1
callback: 2
callback: 3
selesai
(n) => { ... }adalah fungsi yang dikirim keforEachsebagai argumen. Fungsi yang dikirim begini namanya callback.forEachyang memanggil callback itu, sekali per item, dan tiap kali mengisindengan item tersebut.selesaibaru tercetak setelah semua callback beres, karenaforEachmenunggu callback-nya selesai.
Patokannya: callback adalah fungsi yang kamu kirim, dan fungsi penerimanya yang memanggil.
Bikin fungsi yang menerima callback
function hitung(a, b, operasi) {
return operasi(a, b);
}
console.log(hitung(6, 3, (x, y) => x + y)); // 9
console.log(hitung(6, 3, (x, y) => x * y)); // 18
operasiadalah parameter biasa, cuma isinya sebuah fungsi.operasi(a, b)memanggil fungsi itu. Tanpa(),operasicuma fungsinya, belum dijalankan.- Yang di-return callback (
x + y) jadi hasiloperasi(a, b), laluhitungme-return hasil itu. hitungyang sama bisa menjumlah atau mengali, tergantung callback yang dikirim.
Array punya method yang sudah menerima callback dan mengembalikan array baru:
arr.map(cb)berisi hasilcbbuat tiap item:[1, 2, 3].map((x) => x * 10)menghasilkan[10, 20, 30].arr.filter(cb)cuma berisi item yangcb-nya menghasilkantrue:[1, 2, 3].filter((x) => x > 1)menghasilkan[2, 3].
Callback yang dipanggil nanti
console.log("mulai");
setTimeout(() => {
console.log("1 detik kemudian");
}, 1000);
console.log("selesai");
Yang tercetak: mulai, selesai, lalu 1 detik kemudian. setTimeout(callback, ms) cuma menitip callback-nya, lalu kode di bawahnya jalan terus tanpa menunggu. Callback-nya dipanggil setelah 1000 milidetik (1 detik). Jadi jawaban tebakannya: gak nunggu. addEventListener juga begitu: callback-nya dipanggil nanti, tiap kali event-nya terjadi.
Callback di dalam callback
Kalau beberapa langkah harus jalan berurutan, callback-nya bersarang makin dalam:
setTimeout(() => {
console.log("langkah 1");
setTimeout(() => {
console.log("langkah 2");
setTimeout(() => {
console.log("langkah 3");
}, 500);
}, 500);
}, 500);
Tiap langkah baru mulai setelah langkah sebelumnya selesai, jadi kodenya menjorok makin ke kanan. Bentuk ini dijuluki callback hell: susah dibaca dan susah dicari salahnya. Promise dan async/await, yang dibahas di pelajaran berikutnya, bikin langkah yang sama jadi rata.
⚠️ Jebakan yang sering ketemu
- Menulis
()waktu mengirim callback.numbers.forEach(cetak())menjalankancetaksaat itu juga dan mengirim hasilnya. Tulisnumbers.forEach(cetak). - Lupa
returndi callback berkurung kurawal.(x) => { x * 2 }menghasilkanundefined. Tulis(x) => x * 2atau(x) => { return x * 2; }. - Mencetak, bukan me-return. Fungsi yang cuma
console.loghasilnya tanpareturnbikin pemanggilnya dapatundefined.
TL;DR: Callback adalah fungsi yang dikirim ke fungsi lain, lalu fungsi itu yang memanggilnya, misalnya forEach, map, filter, setTimeout, dan addEventListener. Kirim fungsinya tanpa (), dan panggil dengan cb() di dalam fungsi penerimanya. forEach memanggil callback-nya saat itu juga, setTimeout memanggilnya nanti sementara kode lain jalan terus. Callback yang bersarang makin dalam dijuluki callback hell, dan Promise atau async/await merapikannya.