javascript
examples
examples.js⚡javascript
/**
* ============================================
* 6.4 THE EVENT LOOP - EXAMPLES
* ============================================
*/
/**
* EXAMPLE 1: Basic Event Loop
* ---------------------------
* Sync code runs before async
*/
console.log('=== Example 1: Basic Event Loop ===');
console.log('1. First (sync)');
setTimeout(() => {
console.log('3. Third (async)');
}, 0);
console.log('2. Second (sync)');
// Output: 1, 2, 3
/**
* EXAMPLE 2: setTimeout 0 is NOT Immediate
* ----------------------------------------
* Even 0ms delay goes through the queue
*/
console.log('\n=== Example 2: setTimeout 0 ===');
console.log('Start');
setTimeout(() => console.log('Timeout 1'), 0);
setTimeout(() => console.log('Timeout 2'), 0);
setTimeout(() => console.log('Timeout 3'), 0);
console.log('End');
// All sync code runs first, then timeouts in order
/**
* EXAMPLE 3: Microtasks vs Macrotasks
* -----------------------------------
* Promises (microtasks) run before setTimeout (macrotasks)
*/
console.log('\n=== Example 3: Micro vs Macro ===');
console.log('1. Sync start');
setTimeout(() => {
console.log('4. Timeout (macrotask)');
}, 0);
Promise.resolve().then(() => {
console.log('3. Promise (microtask)');
});
console.log('2. Sync end');
// Output: 1, 2, 3, 4
/**
* EXAMPLE 4: Multiple Promises
* ----------------------------
* All microtasks run before any macrotask
*/
console.log('\n=== Example 4: Multiple Promises ===');
setTimeout(() => console.log('6. Timeout'), 0);
Promise.resolve().then(() => console.log('2. Promise 1'));
Promise.resolve().then(() => console.log('3. Promise 2'));
Promise.resolve().then(() => console.log('4. Promise 3'));
console.log('1. Sync');
setTimeout(() => console.log('7. Timeout 2'), 0);
Promise.resolve().then(() => console.log('5. Promise 4'));
// All promises (2-5) run before timeouts (6-7)
/**
* EXAMPLE 5: Nested Microtasks
* ----------------------------
* Microtasks can queue more microtasks
*/
console.log('\n=== Example 5: Nested Microtasks ===');
setTimeout(() => console.log('5. Timeout'), 0);
Promise.resolve()
.then(() => {
console.log('1. Promise A');
Promise.resolve().then(() => {
console.log('3. Nested Promise');
});
})
.then(() => console.log('4. Promise A.then'));
Promise.resolve().then(() => console.log('2. Promise B'));
// Nested microtasks still run before macrotasks
/**
* EXAMPLE 6: queueMicrotask
* -------------------------
* Explicit way to queue microtasks
*/
console.log('\n=== Example 6: queueMicrotask ===');
console.log('1. Start');
setTimeout(() => console.log('4. Timeout'), 0);
queueMicrotask(() => {
console.log('2. Microtask 1');
});
queueMicrotask(() => {
console.log('3. Microtask 2');
});
console.log('Sync continues...');
// queueMicrotask has same priority as Promise.then
/**
* EXAMPLE 7: Async/Await is Microtask-Based
* -----------------------------------------
* await yields to microtask queue
*/
console.log('\n=== Example 7: Async/Await ===');
async function asyncFunc() {
console.log('2. Async function start');
await Promise.resolve();
console.log('4. After await'); // This is a microtask!
}
console.log('1. Before async call');
asyncFunc();
console.log('3. After async call');
// await splits function into before/after microtask
/**
* EXAMPLE 8: setInterval
* ----------------------
* Repeated macrotasks
*/
console.log('\n=== Example 8: setInterval ===');
let count = 0;
const intervalId = setInterval(() => {
count++;
console.log(`Interval tick: ${count}`);
if (count >= 3) {
clearInterval(intervalId);
console.log('Interval stopped');
}
}, 100);
console.log('Interval started');
/**
* EXAMPLE 9: Event Loop Blocking
* ------------------------------
* Sync code blocks the loop
*/
console.log('\n=== Example 9: Blocking ===');
console.log('Before blocking');
setTimeout(() => {
console.log('Timeout (was waiting)');
}, 0);
// This blocks for ~100ms
const blockEnd = Date.now() + 100;
while (Date.now() < blockEnd) {
// Blocking the event loop!
}
console.log('After blocking');
// The timeout waited for the blocking code to finish
/**
* EXAMPLE 10: Non-Blocking Pattern
* --------------------------------
* Break up work to avoid blocking
*/
console.log('\n=== Example 10: Non-Blocking ===');
function processChunk(items, index, callback) {
if (index >= items.length) {
callback('Done!');
return;
}
// Process one item
console.log(`Processing item ${index}: ${items[index]}`);
// Yield to event loop, then continue
setTimeout(() => {
processChunk(items, index + 1, callback);
}, 0);
}
const items = ['a', 'b', 'c', 'd', 'e'];
processChunk(items, 0, (result) => {
console.log('Result:', result);
});
console.log('Processing started (non-blocking)');
/**
* EXAMPLE 11: Promise Chain
* -------------------------
* Each .then creates a new microtask
*/
console.log('\n=== Example 11: Promise Chain ===');
Promise.resolve('Start')
.then((val) => {
console.log('Step 1:', val);
return 'Step 1 complete';
})
.then((val) => {
console.log('Step 2:', val);
return 'Step 2 complete';
})
.then((val) => {
console.log('Step 3:', val);
return 'Step 3 complete';
})
.then((val) => {
console.log('Final:', val);
});
console.log('Chain initiated');
/**
* EXAMPLE 12: Promise.all and Event Loop
* --------------------------------------
* Parallel promises, ordered results
*/
console.log('\n=== Example 12: Promise.all ===');
const delay = (ms, value) =>
new Promise((resolve) => setTimeout(() => resolve(value), ms));
console.log('Starting parallel promises');
Promise.all([delay(30, 'A'), delay(10, 'B'), delay(20, 'C')]).then(
(results) => {
console.log('All complete:', results);
// Order matches input, not completion time
}
);
console.log('Waiting for promises...');
/**
* EXAMPLE 13: Error Handling and Event Loop
* -----------------------------------------
* Uncaught promise errors
*/
console.log('\n=== Example 13: Promise Errors ===');
// Caught error
Promise.reject('Error 1').catch((err) => console.log('Caught:', err));
// This runs before the catch
console.log('After promise rejection');
/**
* EXAMPLE 14: Mixing Sync, Microtask, Macrotask
* ---------------------------------------------
* Complex example to trace
*/
console.log('\n=== Example 14: Complex Mix ===');
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve()
.then(() => console.log('3'))
.then(() => console.log('4'));
setTimeout(() => console.log('5'), 0);
Promise.resolve().then(() => {
console.log('6');
setTimeout(() => console.log('7'), 0);
});
console.log('8');
// Output: 1, 8, 3, 6, 4, 2, 5, 7
/**
* EXAMPLE 15: requestAnimationFrame (Browser Only)
* ------------------------------------------------
* Runs before next paint
*/
console.log('\n=== Example 15: requestAnimationFrame ===');
if (typeof requestAnimationFrame !== 'undefined') {
console.log('1. Start');
requestAnimationFrame(() => {
console.log('3. Animation frame');
});
console.log('2. End');
} else {
console.log('requestAnimationFrame not available (Node.js)');
}
/**
* EXAMPLE 16: setImmediate (Node.js)
* -----------------------------------
* Node-specific immediate execution
*/
console.log('\n=== Example 16: Node.js specifics ===');
if (typeof setImmediate !== 'undefined') {
setTimeout(() => console.log('setTimeout'), 0);
setImmediate(() => console.log('setImmediate'));
// Order varies depending on when event loop starts
} else {
console.log('setImmediate not available (Browser)');
}
/**
* EXAMPLE 17: Tracing Event Loop Order
* ------------------------------------
* Helper to visualize order
*/
console.log('\n=== Example 17: Tracing Tool ===');
function trace(label) {
console.log(`[${new Date().toISOString().slice(-13, -1)}] ${label}`);
}
trace('Sync 1');
setTimeout(() => trace('Macro 1'), 0);
setTimeout(() => trace('Macro 2'), 10);
Promise.resolve().then(() => trace('Micro 1'));
queueMicrotask(() => trace('Micro 2'));
trace('Sync 2');
/**
* EXAMPLE 18: Common Interview Pattern
* ------------------------------------
* Classic event loop question
*/
console.log('\n=== Example 18: Interview Question ===');
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function () {
console.log('setTimeout');
}, 0);
async1();
new Promise(function (resolve) {
console.log('promise1');
resolve();
}).then(function () {
console.log('promise2');
});
console.log('script end');
// Output:
// script start
// async1 start
// async2
// promise1
// script end
// async1 end
// promise2
// setTimeout
console.log('\n=== End of Examples ===');
console.log('Note: Some examples have delayed output.');
console.log('Wait a moment to see all results.');