JavaScript Event Loop & Concurrency
JavaScript is single-threaded but can handle concurrent operations through the event loop, which manages the execution of code, events, and callbacks.
Call Stack, Web APIs, and Task Queue
console.log('Start');
setTimeout(() => {
console.log('Timeout');
}, 0);
Promise.resolve()
.then(() => console.log('Promise 1'))
.then(() => console.log('Promise 2'));
console.log('End');
// Output:
// Start
// End
// Promise 1
// Promise 2
// Timeout
// Why? Execution order:
// 1. Synchronous code runs first (Call Stack)
// 2. Microtasks (Promises) run next (Microtask Queue)
// 3. Macrotasks (setTimeout, setInterval) run last (Task Queue)Microtasks vs Macrotasks
// Microtasks (higher priority):
// - Promise callbacks (.then, .catch, .finally)
// - queueMicrotask()
// - MutationObserver
// Macrotasks (lower priority):
// - setTimeout, setInterval
// - setImmediate (Node.js)
// - I/O operations
// - UI rendering
console.log('1');
setTimeout(() => console.log('2 - setTimeout'), 0);
Promise.resolve().then(() => console.log('3 - Promise'));
queueMicrotask(() => console.log('4 - queueMicrotask'));
console.log('5');
// Output:
// 1
// 5
// 3 - Promise
// 4 - queueMicrotask
// 2 - setTimeoutWeb Workers (True Concurrency)
// Main thread
const worker = new Worker('worker.js');
// Send message to worker
worker.postMessage({ type: 'CALCULATE', numbers: [1, 2, 3, 4, 5] });
// Receive message from worker
worker.onmessage = (event) => {
console.log('Result from worker:', event.data);
};
worker.onerror = (error) => {
console.error('Worker error:', error);
};
// worker.js
self.onmessage = (event) => {
const { type, numbers } = event.data;
if (type === 'CALCULATE') {
// Heavy computation in separate thread
const result = numbers.reduce((sum, n) => sum + n, 0);
self.postMessage(result);
}
};Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free