Event Loop & Urutan Eksekusi

Memahami cara Node menangani pekerjaan asinkron: call stack, microtask, nextTick, timer, dan setImmediate.

Part 7 dari 24 ± 40 menit Gratis

JavaScript: satu thread, satu pekerjaan

Kode JavaScript berjalan di satu thread dan mengerjakan satu hal pada satu waktu. Lalu bagaimana Node bisa melayani ribuan pengguna sekaligus? Jawabannya: ia tidak menunggu. Operasi lambat (jaringan, disk, timer) diserahkan ke sistem, dan hasilnya ditangani nanti lewat event loop.

Analogi kasir kopi

Barista (thread tunggal) menerima pesanan, menyalakan mesin espresso (operasi lambat), dan tidak berdiri menunggu: ia langsung melayani pelanggan berikutnya. Saat mesin berbunyi (selesai), barista menyelesaikan pesanan itu. Itulah non-blocking I/O.

Komponen utama

  • Call stack: tempat fungsi yang sedang dijalankan.
  • Antrian callback: tempat tugas yang sudah siap menunggu giliran.
  • Event loop: pekerja yang terus memeriksa: "stack kosong? ada tugas siap? jalankan."

Urutan prioritas

Tidak semua tugas setara. Setelah kode sinkron selesai, Node menjalankan antrean dengan urutan:

  1. Kode sinkron (seluruh skrip utama).
  2. process.nextTick() — antrean tertinggi.
  3. Microtask: callback Promise (.then, await), queueMicrotask.
  4. Timers: setTimeout / setInterval yang waktunya tiba.
  5. I/O callbacks: hasil baca file, jaringan.
  6. setImmediate() — fase "check", setelah I/O.

Contoh klasik

console.log('1 sinkron');
setTimeout(() => console.log('5 setTimeout'), 0);
setImmediate(() => console.log('6 setImmediate'));
Promise.resolve().then(() => console.log('4 promise'));
process.nextTick(() => console.log('3 nextTick'));
console.log('2 sinkron akhir');

Keluaran: 1, 2, 3, 4, 5, 6. Perhatikan: setTimeout(fn, 0) bukan "jalankan sekarang" — callback-nya tetap menunggu semua kode sinkron dan microtask selesai.

Catatan: urutan setTimeout(…, 0) versus setImmediate di skrip utama tidak dijamin di Node asli (biasanya timeout dulu). Di dalam callback I/O, setImmediate selalu lebih dulu. Simulator KelasIT memakai urutan yang umum.

Dampak praktis: jangan blokir event loop

// MEMBLOKIR — semua pengguna lain menunggu 5 detik!
app.get('/hitung', (req, res) => {
  const mulai = Date.now();
  while (Date.now() - mulai < 5000) {}   // perhitungan berat sinkron
  res.send('selesai');
});

Pekerjaan CPU berat sebaiknya dipindah ke worker_threads atau proses terpisah. Pekerjaan I/O aman karena asinkron.

setTimeout dan setInterval

const t = setTimeout(() => console.log('sekali'), 1000);
clearTimeout(t);                          // batalkan sebelum jalan
const i = setInterval(() => console.log('berulang'), 500);
setTimeout(() => clearInterval(i), 2100);  // hentikan interval

Waktu pada timer adalah minimum, bukan jaminan: jika event loop sedang sibuk, callback bisa terlambat.

Dua tipe penjadwalan "segera"

  • process.nextTick: sebelum Promise; berlebihan memakainya bisa "kelaparan" (starve) I/O.
  • queueMicrotask / Promise: setelah nextTick, sebelum timer.
  • setImmediate: setelah fase I/O saat ini.

Praktikkan langsung, gratis

Tulis dan jalankan kode langsung di browser, dapatkan penilaian otomatis. Daftar gratis kapan saja untuk menyimpan progres dan meraih sertifikat.

Coba latihan sekarang, tanpa daftar
Bagikan: WhatsApp Facebook LinkedIn X