JavaScript Event Loop yaj
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.