javascript

examples

examples.js
/**
 * ============================================
 * 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.');
Examples - JavaScript Tutorial | DeepML