JavaScript mengerjakan kode satu per satu, satu hal dalam satu waktu. Kode yang harus menunggu, misalnya timer, gak dikerjakan saat itu juga: dia dititip ke antrean dan dijalankan nanti. Event loop adalah aturan yang menentukan kapan tiap antrean dapat giliran.
🧪 Tebakan cepat:
setTimeout(..., 0)artinya tunggu 0 milidetik. Apa callback-nya langsung jalan sebelum baris berikutnya? Tebak dulu, jawabannya ada di bagian "Tebak urutan cetaknya".
Tebak urutan cetaknya
console.log("A");
setTimeout(() => {
console.log("B");
}, 0);
Promise.resolve().then(() => {
console.log("C");
});
console.log("D");
Yang tercetak: A, D, C, B. Langkahnya:
console.log("A")langsung jalan.setTimeout(..., 0)gak menjalankan callback-nya sekarang. Callback itu masuk antrean task, walaupun waktunya 0 milidetik.Promise.resolve()bikin Promise, semacam janji, yang di sini langsung selesai..then(...)menitip callback buat jalan sesudah janjinya selesai, dan titipan itu masuk antrean lain: antrean microtask. Promise dibahas lengkap di pelajaran Fetch & Promises.console.log("D")langsung jalan.- Kode utama habis. Sekarang semua microtask dikerjakan dulu (
C), baru satu task (B).
Jadi jawaban tebakannya: gak. 0 milidetik cuma berarti "secepatnya", dan secepatnya itu tetap sesudah kode utama dan semua microtask selesai.
Aturan yang mengatur urutan ini namanya event loop. Patokannya: kode biasa dulu dari atas ke bawah, lalu semua callback Promise, baru callback setTimeout.
Tiga tempat kode menunggu giliran
- Call stack: kode yang sedang jalan saat ini, dikerjakan satu per satu sampai kosong.
- Microtask queue: antrean callback
.thendari Promise, kode sesudahawait, danqueueMicrotask. Antrean ini didahulukan. - Task queue (sering disebut macrotask queue): antrean callback
setTimeout,setInterval, klik, dan event lain.
Event loop mengulang tiga langkah yang sama terus-menerus:
- Jalankan call stack sampai kosong.
- Kerjakan semua microtask sampai antreannya habis.
- Ambil satu task, lalu balik ke langkah 1.
Jadi microtask selalu selesai duluan sebelum task berikutnya jalan, walaupun task-nya ditulis lebih dulu.
⚠️ Jebakan yang sering ketemu
- Mengira urutan tulis sama dengan urutan jalan.
setTimeoutyang ditulis duluan bisa jalan paling akhir. - Kode sesudah
awaitjalan belakangan.awaitmenjeda fungsinya, dan sisanya antre sebagai microtask, jadi kode di luar fungsi itu jalan duluan. - Loop berat membekukan halaman. Selama call stack sibuk, klik dan gambar ulang layar ikut menunggu. Pecah kerjaan yang berat jadi bagian kecil.
🔬 Coba sendiri
Alat di bawah menjalankan beberapa program langkah demi langkah, termasuk async/await, dan menandai mana yang jalan langsung, mana yang microtask, dan mana yang macrotask.
TL;DR: JavaScript menjalankan satu hal dalam satu waktu, dan event loop menentukan urutannya: kode biasa di call stack dulu, lalu semua microtask (callback .then dari Promise, kode sesudah await), baru satu macrotask (callback setTimeout, klik). Ulang terus. Karena itu setTimeout(fn, 0) tetap jalan sesudah Promise, dan loop yang berat bikin halaman membeku.