Callback: Fungsi dalam Fungsi
Konsep callback dan callback hell
Tujuan Pembelajaran
- Memahami konsep callback function
- Mengerti masalah callback hell dan solusinya
Analogi
Callback = Surat Pengingat:
Kamu: 'Mas, kalau nasi gorengnya jadi, antar ke meja 5 ya.'
Pelayan: 'Oke, saya ingat.'
(Nasi goreng jadi)
Pelayan: 'Ini untuk meja 5!' (callback dipanggil)
Callback = 'panggil saya kalau sudah selesai'
Penjelasan Konsep
Bayangkan kamu berada di tengah keramaian konser musik. Ada ribuan orang, dan kamu ingin memberikan sesuatu ke orang-orang tertentu. Kalau kamu teriak “Halo semua!”, semua orang akan menoleh — itu adalah selektor universal. Tapi kalau kamu bilang “Kaos merah maju!”, cuma yang pakai kaos merah yang maju — itu adalah selektor class.
Kalau kamu sebut nama “Budi!”, hanya Budi yang merespons — itu adalah selektor ID. CSS bekerja dengan cara yang sama: selektor menentukan elemen mana yang akan menerima styling.
Selektor Dasar
Selektor Elemen (Type Selector)
Memilih semua elemen dengan tag tertentu.
h1 { color: blue; } → Semua h1 jadi biru.
p { font-size: 14px; } → Semua paragraf jadi 14px.
Paling umum digunakan untuk styling global dan reset dasar.
Selektor Class (.)
Memilih elemen dengan class tertentu.
Satu elemen bisa punya banyak class, dan banyak elemen bisa punya class yang sama. Inilah yang membuat class sangat fleksibel dan menjadi selektor yang paling sering digunakan.
.btn { padding: 10px; } → Semua elemen dengan class=“btn”
.btn.primary { background: blue; } → Elemen dengan class=“btn primary” (dua class sekaligus!)
Selektor ID (#)
Memilih elemen dengan ID tertentu. ID harus UNIK di satu halaman — tidak boleh ada dua elemen dengan ID sama.
Karena unik, ID punya specificity tertinggi di antara selektor dasar.
#header { height: 80px; } → Elemen dengan id=“header”
4. Selektor Descendant (Spasi) — Memilih elemen yang berada di dalam elemen lain,
Tidak peduli seberapa dalam.
nav a { color: red; } → Semua <a> yang ada di dalam <nav>
.card p { font-size: 12px; } → Semua <p> di dalam elemen dengan class=“card”
5. Selektor Child Direct (>) — Memilih elemen yang LANGSUNG menjadi anak (bukan cucu atau lebih dalam).
ul > li { list-style: square; } → Hanya <li> yang langsung di dalam <ul>
6. Selektor Adjacent Sibling (+) — Memilih elemen yang bersebelahan langsung setelah elemen tertentu.
h2 + p { margin-top: 0; } → Paragraf yang langsung setelah h2
Pseudo-class: Selektor Keadaan
Pseudo-class memilih elemen berdasarkan keadaan (state) tertentu:
:hover— Saat mouse berada di atas elemen:focus— Saat elemen sedang difokus (klik atau tab):active— Saat elemen sedang di-klik (ditahan):first-child— Elemen pertama di antara saudaranya:last-child— Elemen terakhir:nth-child(n)— Elemen ke-n:not(selector)— Elemen yang TIDAK cocok dengan selektor
Pseudo-element: Bagian Elemen
Pseudo-element men-target bagian spesifik dari elemen:
::before— Menambahkan konten sebelum elemen::after— Menambahkan konten setelah elemen::first-line— Baris pertama teks::first-letter— Huruf pertama teks
Specificity: Siapa yang Menang?
Ketika dua aturan CSS bertabrakan, specificity menentukan mana yang menang:
- Inline style (1000 poin) — paling kuat
- ID selector (100 poin) —
#header - Class/pseudo-class/attribute (10 poin) —
.btn,:hover,[type="text"] - Elemen/pseudo-element (1 poin) —
div,::before
Specificity dihitung dengan sistem ini.
Contoh: #nav .menu a = 100 + 10 + 1 = 111 poin.
Aturan Cascade
Kalau specificity sama,
Aturan yang ditulis TERAKHIR yang menang.
Aturan !important
Menimpa semua specificity.
Gunakan dengan sangat hemat!
Contoh Kode
// CALLBACK HELL
getUser(1, (user) => {
getOrders(user.id, (orders) => {
getProducts(orders[0].id, (products) => {
getReviews(products[0].id, (reviews) => {
console.log(reviews); // Menjorok terus...
});
});
});
});
// SOLUSI: REFACTOR KE FUNGSI TERPISAH
function handleUser(user) {
getOrders(user.id, handleOrders, handleError);
}
function handleOrders(orders) {
getProducts(orders[0].id, handleProducts, handleError);
}
function handleProducts(products) {
getReviews(products[0].id, handleReviews, handleError);
}
function handleReviews(reviews) {
console.log(reviews);
}
function handleError(err) {
console.error(err);
}
getUser(1, handleUser, handleError); // Lebih rapi!Penjelasan Kode
Prompt AI
Jelaskan kenapa callback hell disebut 'pyramid of doom'. Apa kelemahannya?
Pertanyaan Reflektif
Cari kode callback bersarang di proyekmu. Berapa level nesting terdalam? Coba refactor.