Event loop JavaScript adalah mekanisme yang membuat JavaScript tetap responsif, padahal bahasa ini hanya punya satu thread. Tanpa event loop, halaman web akan membeku setiap kali menunggu data dari server atau timer selesai. Jika Anda pernah heran mengapa setTimeout dengan jeda 0 detik tetap berjalan paling akhir, jawabannya ada di sini.
Pada artikel ini, kita bahas cara kerja event loop langkah demi langkah. Anda akan mengenal call stack, Web API, task queue, dan microtask queue. Semuanya dilengkapi contoh kode agar mudah dipahami, bahkan untuk pemula.

Apa Itu Event Loop JavaScript?
JavaScript bersifat single-threaded, artinya hanya satu perintah yang bisa dieksekusi pada satu waktu. Meski begitu, JavaScript mampu menangani permintaan jaringan, klik pengguna, dan timer secara bersamaan. Kuncinya adalah event loop JavaScript.
Event loop adalah proses yang terus berputar dan memeriksa dua hal. Pertama, apakah call stack sudah kosong. Kedua, apakah ada tugas yang menunggu di antrean. Jika stack kosong dan antrean berisi tugas, event loop memindahkan tugas itu ke stack untuk dijalankan. Penjelasan resminya bisa Anda baca di dokumentasi MDN tentang event loop.
Komponen Utama di Balik Layar
Sebelum membahas alurnya, kenali dulu bagian-bagian yang terlibat:
- Call stack: tempat JavaScript mencatat fungsi yang sedang berjalan. Konsepnya last in, first out.
- Web API: fitur bawaan browser seperti
setTimeout,fetch, dan event DOM. Fitur ini berjalan di luar mesin JavaScript. - Task queue (macrotask): antrean untuk callback dari
setTimeout,setInterval, dan event seperti klik. - Microtask queue: antrean berprioritas lebih tinggi untuk callback Promise (
.then,.catch,.finally) danqueueMicrotask. - Event loop: penghubung yang memindahkan tugas dari antrean ke call stack.
Cara Kerja Event Loop Langkah demi Langkah
Berikut urutan sederhana yang terjadi pada cara kerja event loop di browser:
- JavaScript menjalankan kode sinkron dari atas ke bawah di call stack.
- Saat bertemu operasi asinkron seperti
setTimeoutataufetch, tugas itu diserahkan ke Web API. - Setelah selesai, Web API menaruh callback ke antrean yang sesuai.
- Ketika call stack kosong, event loop mengeksekusi semua microtask lebih dulu.
- Browser kemudian bisa memperbarui tampilan layar.
- Event loop mengambil satu tugas dari task queue, lalu siklus berulang.
Poin terpenting: microtask selalu didahulukan sebelum task berikutnya.
Contoh Event Loop JavaScript: Tebak Urutan Outputnya
Perhatikan kode berikut, lalu coba tebak hasilnya sebelum membaca jawabannya.
console.log('1');
setTimeout(() => {
console.log('2');
}, 0);
Promise.resolve().then(() => {
console.log('3');
});
console.log('4');
Outputnya adalah 1, 4, 3, 2. Berikut alasannya:
1dan4adalah kode sinkron, sehingga langsung berjalan.3berasal dari Promise, yang masuk ke microtask queue dan dijalankan setelah kode sinkron selesai.2berasal darisetTimeout, yang masuk ke task queue dan baru berjalan setelah microtask habis.
Karena itu, jeda 0 milidetik pada setTimeout bukan berarti dijalankan seketika. Angka itu hanya waktu minimum, bukan jaminan.

Event Loop JavaScript pada async/await
Sintaks async/await hanyalah cara penulisan Promise yang lebih rapi. Di balik layar, bagian kode setelah await dijalankan sebagai microtask. Coba lihat contoh ini:
async function a() {
console.log('A1');
await b();
console.log('A2');
}
async function b() {
console.log('B');
}
console.log('start');
a();
console.log('end');
Hasilnya: start, A1, B, end, A2. Fungsi a() berjalan sinkron sampai bertemu await. Setelah itu, sisa fungsi ditunda sebagai microtask, sehingga end tercetak lebih dulu.
Pola ini sering muncul saat memanggil API. Misalnya, saat Anda mengambil data dari server seperti dalam pembahasan REST API vs GraphQL, kode di bawah await baru berjalan setelah data datang. Hasil responsnya pun perlu ditangani dengan aman, misalnya memakai optional chaining di JavaScript.
Apa yang Terjadi Jika Call Stack Terblokir?
Event loop hanya bisa bekerja saat call stack kosong. Jika ada kode sinkron yang berjalan lama, seluruh antrean harus menunggu. Contohnya:
setTimeout(() => console.log('Timer selesai'), 1000);
const mulai = Date.now();
while (Date.now() - mulai < 3000) {
// loop berat selama 3 detik
}
console.log('Loop selesai');
Meskipun timer diatur 1 detik, Timer selesai baru tercetak setelah loop berat selesai, yaitu sekitar 3 detik. Selama itu pula halaman web akan terasa macet. Inilah alasan operasi berat tidak boleh dijalankan langsung di thread utama.
Event Loop di Node.js: Apa Bedanya?
Konsepnya serupa, tetapi Node.js memakai library libuv dan membagi siklusnya ke beberapa fase, seperti timers, poll, dan check. Ada dua hal khas di Node.js:
setImmediateberjalan di fase check, yaitu setelah fase poll selesai.process.nextTickdijalankan sebelum microtask Promise.
Detail lengkapnya tersedia di dokumentasi resmi Node.js. Jika Anda mulai belajar Node.js, pahami juga cara mengelola konfigurasi lewat environment variable dan file .env di Node.js.
Tips Menulis Kode yang Ramah Event Loop
Agar aplikasi tetap lancar, terapkan kebiasaan berikut:
- Hindari loop berat di thread utama. Pecah pekerjaan besar menjadi bagian kecil.
- Gunakan Web Worker untuk komputasi berat di browser.
- Pilih API asinkron untuk operasi jaringan dan file.
- Jangan membuat microtask berantai tanpa henti. Microtask yang terus bertambah akan menahan task lain dan pembaruan layar.
- Gunakan
requestAnimationFrameuntuk animasi agar sinkron dengan penyegaran layar. - Tulis kode yang mudah dibaca. Urutan eksekusi asinkron sudah membingungkan, jadi jaga strukturnya tetap rapi. Panduannya ada di artikel pentingnya code readability.
Pemahaman ini juga membantu saat Anda belajar framework. Misalnya, pembaruan state di React bersifat asinkron, seperti yang dibahas pada artikel component, props, dan state dalam React.
Pertanyaan yang Sering Diajukan tentang Event Loop
Apakah JavaScript benar-benar single-threaded?
Ya, mesin JavaScript menjalankan kode di satu thread utama. Namun, browser dan Node.js menyediakan komponen lain yang bekerja di luar thread tersebut, sehingga tugas asinkron tetap bisa berjalan.
Mana yang lebih dulu, microtask atau macrotask?
Microtask selalu dijalankan lebih dulu. Setelah satu task selesai, event loop mengosongkan seluruh microtask sebelum mengambil task berikutnya.
Mengapa setTimeout 0 tidak langsung berjalan?
Callback-nya masuk ke task queue dan harus menunggu call stack serta microtask selesai. Selain itu, browser bisa menerapkan jeda minimum pada timer.
Apakah async/await membuat kode berjalan paralel?
Tidak. async/await hanya mengatur urutan kode asinkron agar lebih mudah dibaca. Eksekusinya tetap berjalan di satu thread.
Kesimpulan
Event loop JavaScript adalah fondasi dari semua kode asinkron, mulai dari timer, Promise, sampai fetch. Ingat tiga hal utama: JavaScript menjalankan satu tugas per waktu, microtask didahulukan sebelum task, dan kode sinkron yang berat akan memblokir segalanya.
Setelah memahami cara kerja event loop, Anda akan lebih mudah menebak urutan eksekusi dan menemukan bug asinkron. Cobalah semua contoh kode di atas di konsol browser untuk melihat hasilnya langsung.
Artikel Terkait Lainnya
- Optional Chaining JavaScript: Cara Pakai ?. dan ?? dengan Benar
- Memahami Component, Props, dan State dalam React untuk Pemula
- Environment Variable: Cara Pakai .env di Node.js
- REST API vs GraphQL: Mana yang Lebih Cocok untuk Proyek Web Modern?
- Kode Sulit Dipahami Setelah Beberapa Bulan? Kenali Pentingnya Code Readability
Temukan lebih banyak tutorial di kategori Bahasa Pemrograman dan Web Development.