Blog Hoch
Jun 2026·2 tup leghDe'wI' chenmoHta'

JavaScript Event Loop yaj

#javascript#async#performance

JavaScript wa' thread Daq Qu' 'ach network requests, timers, UI events law' (block pagh) Qu'. event loop 'oH mIw. order Sov vaj "qatlh 'oH wa'DIch?" bugs yajchoH.

wa' thread, wa' call stack

JavaScript wa' code poH wa' neH Qu'. function call Hoch call stack Daq frame chel. stack chaD vaj engine pIm legh. 'ach tlhoch stack: timers, promises, I/O callbacks, DOM events nom Qu'be' - queue Daq, event loop qaSDI' tlhap.

console.log('1');

setTimeout(() => console.log('2'), 0);

Promise.resolve().then(() => console.log('3'));

console.log('4');

1, 4, 3, 2 ghItlh - 1, 2, 3, 4 pagh. wa' queue pagh, cha' (Dung law') queues.

cha' queues

Macrotasks ("task queue"): setTimeout, setInterval, I/O callbacks, UI events. Microtasks: promise callbacks (.then, .catch, .finally) 'ej queueMicrotask.

event loop rule: script Qu' 'ej call stack chaD vaj Hoch microtask queue drain (chu' microtasks je) - macrotask wa' Qu' qaSpa'.

vaj 3 2 qaSpa' ghItlh: Promise.resolve().then(...) microtask, setTimeout(..., 0) macrotask. microtasks reH Qap.

function logOrder() {
  console.log('start');

  setTimeout(() => console.log('macrotask'), 0);

  Promise.resolve()
    .then(() => console.log('microtask 1'))
    .then(() => console.log('microtask 2'));

  console.log('end');
}

logOrder();
// start
// end
// microtask 1
// microtask 2
// macrotask

cha' chained .then() setTimeout callback qaSpa' Qu' (0ms delay 'ach) - microtask queue wa'DIch drain.

setTimeout(fn, 0) "DaH" pagh

0 delay "nom Qu'" pagh. "nom laH 'ach call stack chaD 'ej microtask queue drain qaSDI'". browsers nested timeouts 4ms Dach. setTimeout(fn, 0) work defer vaD Dun - synchronous pagh microtask code rap interleave pagh.

UI update tlhoy' qatlh

function expensiveWork() {
  let sum = 0;
  for (let i = 0; i < 1e9; i++) sum += i;
  return sum;
}

showLoadingSpinner(); // updates the DOM
const result = expensiveWork(); // blocks the thread
hideLoadingSpinner();

spinner tu'lu'be'. showLoadingSpinner() DOM update schedule 'ach browser call stack chaD qaSpa' paint laHbe' - expensiveWork() stack busy. Qotlh: heavy work qaSpa' event loop yIchaw':

function showSpinnerThenWork() {
  showLoadingSpinner();

  setTimeout(() => {
    const result = expensiveWork();
    hideLoadingSpinner();
    renderResult(result);
  }, 0);
}

spinner update paint expensiveWork() qaSpa'. work tIn vaD Web Worker Dun - setTimeout(fn, 0) wa'DIch paint neH.

async/await microtask sugar

async functions chu' concurrency primitives pagh - promises 'ej microtask queue neH. await function suspend 'ej continuation microtask schedule.

async function sequence() {
  console.log('a');
  await null;
  console.log('b');
}

console.log('before');
sequence();
console.log('after');

// before
// a
// after
// b

await null microtask queue chaw' (null resolved 'ach) - await qaSDI' continuation synchronous Qu'be'.

microtasks event loop starve

microtask queue Hoch drain macrotask qaSpa'. microtask microtasks chel reH vaj rendering 'ej I/O starve:

function recurse() {
  Promise.resolve().then(recurse);
}
recurse(); // freezes the tab — the loop never reaches a macrotask

recursive promise chains Daq footgun: .then() callback jIH requeue vaj page lock. setTimeout browser breathe.

yaj

event loop order arbitrary pagh: synchronous code wa'DIch, Hoch microtask queue drain, wa' macrotask, microtask queue drain, ... Promises 'ej async/await microtask lane; timers, I/O, UI events macrotask lane. lane Sov vaj order Sov.

chu'GitHub Action wa'DIch ghItlhqanNode.js Memory Leaks debug