JSFlow

Dark Mode
Language

Code Examples

Async Basics
Event Loop
Timer Patterns
Microtask Queue
Promise Patterns
Network & Fetch
Error Handling
Common Patterns
Advanced

Code Editor

0/0
Loading...

Call Stack (0)
?
Call Stack - Stack that stores information about executing functions
  • LIFO Structure: Last In, First Out - last called function executes first
  • Execution Context: Each function creates its own context containing variables and parameters
  • Stack Frame: Each frame contains information about a running function
How it works:
  • When calling function → Push to top of stack
  • When function ends → Pop from stack
  • Function at top of stack is currently running
  • Stack empty → Event Loop can process async tasks
Example: a() calls b() calls c() → Stack: [a, b, c]

Call stack is empty.
Run some code to see function calls.

Web APIs
?
Web APIs - Environment for executing asynchronous tasks outside JavaScript engine
  • Browser APIs: APIs provided by browser (setTimeout, fetch, DOM events...)
  • Non-blocking: Don't block main thread during execution
  • Callback Registration: Register callbacks to handle when completed
Common Web API types:
  • setTimeout/setInterval: Timer APIs - time counting
  • fetch: Network API - HTTP requests
  • DOM Events: User interaction events (click, scroll...)
  • XMLHttpRequest: HTTP requests (legacy)
Workflow:
  • JavaScript calls Web API → Register task
  • Web API processes asynchronously in background
  • When completed → Callback queued to Task Queue
  • Event Loop moves callback to Call Stack when empty
Example: setTimeout(callback, 1000) → Web API counts 1s → callback to Macrotask Queue

Event Loop
?
Event Loop - The mechanism that coordinates execution of asynchronous tasks in JavaScript
  • Single-threaded: JavaScript has only 1 main thread to execute code
  • Non-blocking: Doesn't block UI when processing async operations
  • Continuous Loop: Continuously checks and processes tasks
Operating conditions:
  • Call Stack must be empty (only global context remains)
  • Tasks are waiting in queues
Processing priority order:
1. Microtask Queue - Process ALL microtasks first
2. Macrotask Queue - Process ONE macrotask
3. Repeat - Go back to step 1 if tasks remain
Task types:
  • Microtasks: Promise.then(), queueMicrotask() - high priority
  • Macrotasks: setTimeout(), setInterval() - low priority
Example: Promise.then() always runs before setTimeout() even if setTimeout is called first

Event Loop
Waiting for code execution...

Execution Steps
?
Execution Steps - Detailed log of execution steps (not part of actual JavaScript engine)
  • Purpose: Help you observe and learn how JavaScript engine processes code
  • Nature: Learning tool, not part of browser
Important step types:
  • Console: console.log(), console.error() commands
  • FunctionCall/Return: Function calls and returns
  • CallStackPush/Pop: Add/remove functions from call stack
  • EventLoop: Event Loop operations
  • Microtask/Macrotask: Async task processing
How to use effectively:
  • Step-by-step: Run step by step to understand flow
  • Compare: Cross-reference with Call Stack and Task Queues
  • Analyze: Find out why execution order is like this
  • Debug: Click on step to jump to that moment
Important: Focus on step order to understand async behavior
1000ms

No steps yet
No execution steps yet.
Click Run Code to see the execution flow.

Console

> Ready to execute JavaScript code...

Task Queues
?
Task Queues - Queues containing callbacks from async operations waiting to be executed
  • Microtask Queue: Promise callbacks, queueMicrotask() - High priority
  • Macrotask Queue: setTimeout, setInterval, DOM events - Low priority
  • FIFO Structure: First In, First Out - first task will be processed first
Event Loop Priority:
  • 1. Microtasks: Execute ALL microtasks first
  • 2. Macrotasks: Only execute 1 macrotask at a time
  • 3. Repeat: Go back to step 1 if more tasks
Example: setTimeout(0) even written first will run after Promise.resolve()

Micro Task Queue

HIGH PRIORITY

Macro Task Queue

LOW PRIORITY

setTimeout Basics

Learn how setTimeout works in the Event Loop. This demo helps understand the macrotask queue and async execution order.

</>Demo Code
1console.log('Start');
2
3setTimeout(() => {
4    console.log('Timeout callback executed');
5}, 0);
6
7console.log('End');

Promise Fundamentals

Explore how Promise.resolve() creates microtasks. Understand the difference between microtask and macrotask priority.

</>Demo Code
1console.log('Start');
2
3let promise = Promise.resolve('Hello Promise');
4promise.then((value) => {
5    console.log('Promise resolved:', value);
6});
7
8console.log('End');

setTimeout vs Promise

Direct comparison between setTimeout (macrotask) and Promise (microtask). Microtasks are always prioritized over macrotasks.

</>Demo Code
1console.log('Start');
2
3setTimeout(() => {
4    console.log('Timeout (Macrotask)');
5}, 0);
6
7Promise.resolve().then(() => {
8    console.log('Promise (Microtask)');
9});
10
11console.log('End');

Multiple Async Operations

Complex demo with multiple setTimeout and Promise chains. Observe execution order according to Event Loop rules.

</>Demo Code
1console.log('A');
2
3setTimeout(() => {
4    console.log('B');
5}, 0);
6
7Promise.resolve().then(() => {
8    console.log('C');
9    return Promise.resolve();
10}).then(() => {
11    console.log('D');
12});
13
14setTimeout(() => {
15    console.log('E');
16}, 0);
17
18console.log('F');

Promise Chaining

Learn how Promise chains work. Each .then() creates a new microtask after the previous callback completes.

</>Demo Code
1console.log('Start');
2
3Promise.resolve(1)
4    .then((value) => {
5        console.log('First then:', value);
6        return value * 2;
7    })
8    .then((value) => {
9        console.log('Second then:', value);
10        return value + 1;
11    })
12    .then((value) => {
13        console.log('Third then:', value);
14    });
15
16console.log('End');

Multiple setTimeout

Multiple timers with different delays. Understand how WebAPI handles timers and queues callbacks to macrotask queue.

</>Demo Code
1console.log('Start');
2
3setTimeout(() => {
4    console.log('Timer 1 (100ms)');
5}, 100);
6
7setTimeout(() => {
8    console.log('Timer 2 (0ms)');
9}, 0);
10
11setTimeout(() => {
12    console.log('Timer 3 (50ms)');
13}, 50);
14
15setTimeout(() => {
16    console.log('Timer 4 (0ms)');
17}, 0);
18
19Promise.resolve().then(() => {
20    console.log('Promise (Microtask)');
21});
22
23console.log('End');

Microtask Priority

Demo the power of microtask queue. Nested Promise.resolve() creates consecutive microtask chains.

</>Demo Code
1console.log('1');
2
3Promise.resolve().then(() => {
4    console.log('2');
5    Promise.resolve().then(() => console.log('3'));
6});
7
8Promise.resolve().then(() => {
9    console.log('4');
10});
11
12console.log('5');

Nested Promise Patterns

Nested Promises create complex patterns. Learn how microtasks are queued in depth-first order.

</>Demo Code
1console.log('Start');
2
3Promise.resolve()
4    .then(() => {
5        console.log('Promise 1');
6        return Promise.resolve()
7            .then(() => console.log('Nested Promise 1'))
8            .then(() => console.log('Nested Promise 2'));
9    })
10    .then(() => console.log('Promise 2'));
11
12console.log('End');

queueMicrotask API

Compare queueMicrotask() with Promise.resolve().then(). Both create microtasks with similar priority.

</>Demo Code
1console.log('1');
2
3queueMicrotask(() => console.log('2'));
4
5Promise.resolve().then(() => console.log('3'));
6
7queueMicrotask(() => console.log('4'));
8
9console.log('5');

Promise.resolve() Deep Dive

Explore Promise.resolve() creating immediately resolved Promises. Callbacks are still queued to microtasks.

</>Demo Code
1console.log('A');
2
3Promise.resolve('Immediate Value')
4    .then(value => {
5        console.log('B:', value);
6        return 'New Value';
7    })
8    .then(value => {
9        console.log('C:', value);
10    });
11
12console.log('D');

Multiple Independent Promises

Multiple independent Promises running in parallel. All callbacks are queued to microtasks simultaneously.

</>Demo Code
1console.log('Start');
2
3Promise.resolve(1).then(x => console.log('Promise 1:', x));
4Promise.resolve(2).then(x => console.log('Promise 2:', x));
5Promise.resolve(3).then(x => console.log('Promise 3:', x));
6
7setTimeout(() => console.log('Timer 1'), 0);
8setTimeout(() => console.log('Timer 2'), 0);
9
10console.log('End');

Timer + Promise Interaction

Timers containing Promises and vice versa. Observe how microtasks are processed within macrotask callbacks.

</>Demo Code
1console.log('Start');
2
3setTimeout(() => {
4    console.log('Timer start');
5    Promise.resolve().then(() => console.log('Promise in timer'));
6    console.log('Timer end');
7}, 0);
8
9Promise.resolve().then(() => {
10    console.log('Promise start');
11    setTimeout(() => console.log('Timer in promise'), 0);
12    console.log('Promise end');
13});
14
15console.log('End');

Promise.all() Behavior

Compare Promise.all() with individual Promises. Understand how Promise.all() works with resolved promises.

</>Demo Code
1console.log('Start');
2
3const promise1 = Promise.resolve(1);
4const promise2 = Promise.resolve(2);
5const promise3 = Promise.resolve(3);
6
7Promise.all([promise1, promise2, promise3])
8    .then(values => {
9        console.log('Promise.all resolved:', values);
10    });
11
12// Compare with individual promises
13promise1.then(val => console.log('Individual 1:', val));
14promise2.then(val => console.log('Individual 2:', val));
15promise3.then(val => console.log('Individual 3:', val));
16
17console.log('End');

Fetch API Simulation

Simulate fetch requests with Promise chains. Learn how network requests create Promise and callback sequences.

</>Demo Code
1console.log('Start');
2
3// Simulated fetch request
4fetch('https://api.example.com/data')
5    .then(response => {
6        console.log('Fetch resolved:', response);
7        return response;
8    })
9    .then(data => {
10        console.log('Data processed:', data);
11    });
12
13// Other async operations
14setTimeout(() => {
15    console.log('Timer during fetch');
16}, 0);
17
18Promise.resolve().then(() => {
19    console.log('Promise during fetch');
20});
21
22console.log('End');

Promise Error Handling

How Promises handle errors with .catch(). Errors don't affect other async operations in the queue.

</>Demo Code
1console.log('Start');
2
3Promise.resolve()
4    .then(() => {
5        console.log('First promise');
6        throw new Error('Something went wrong');
7    })
8    .then(() => {
9        console.log('This will not run');
10    })
11    .catch(error => {
12        console.log('Caught error:', error.message);
13        return 'Error handled';
14    })
15    .then(result => {
16        console.log('After catch:', result);
17    });
18
19setTimeout(() => {
20    console.log('Timer still runs');
21}, 0);
22
23console.log('End');

Async Recursion Pattern

Recursion with setTimeout avoids stack overflow. Each recursive call creates a new macrotask.

</>Demo Code
1console.log('Start recursion');
2
3function countdown(n) {
4    console.log('Countdown:', n);
5    
6    if (n <= 0) {
7        console.log('Done!');
8        return;
9    }
10    
11    // Async recursion with setTimeout
12    setTimeout(() => {
13        countdown(n - 1);
14    }, 0);
15}
16
17countdown(3);
18console.log('Recursion initiated');

Synchronous Recursion

Sync recursion keeps all calls on the call stack. Observe call stack growth and return sequence.

</>Demo Code
1console.log('Start sync recursion');
2
3function factorial(n) {
4    console.log('Calculating factorial of:', n);
5    
6    if (n <= 1) {
7        console.log('Base case reached');
8        return 1;
9    }
10    
11    // Sync recursion - each call stays on call stack
12    const result = n * factorial(n - 1);
13    console.log('Returning for n =', n, ', result =', result);
14    return result;
15}
16
17const result = factorial(4);
18console.log('Final result:', result);
19console.log('Sync recursion complete');

Callback Pattern (Pre-Promise)

Traditional callback pattern before Promises. Understand 'callback hell' and why Promises were created.

</>Demo Code
1console.log('Start');
2
3function asyncOperation(callback) {
4    setTimeout(() => {
5        console.log('Async operation complete');
6        callback('Result data');
7    }, 0);
8}
9
10function asyncOperation2(data, callback) {
11    setTimeout(() => {
12        console.log('Second operation with:', data);
13        callback('Final result');
14    }, 0);
15}
16
17// Callback pattern (before Promises)
18asyncOperation((result1) => {
19    console.log('First callback:', result1);
20    
21    asyncOperation2(result1, (result2) => {
22        console.log('Second callback:', result2);
23    });
24});
25
26console.log('End');

Complex Event Loop Demo

Most complex demo mixing setTimeout, Promise, nested async. Test your understanding of Event Loop mechanics.

</>Demo Code
1console.log('A');
2
3setTimeout(() => {
4    console.log('B');
5    Promise.resolve().then(() => console.log('C'));
6}, 0);
7
8Promise.resolve()
9    .then(() => {
10        console.log('D');
11        setTimeout(() => console.log('E'), 0);
12        return Promise.resolve();
13    })
14    .then(() => console.log('F'));
15
16setTimeout(() => console.log('G'), 0);
17
18Promise.resolve().then(() => {
19    console.log('H');
20    Promise.resolve().then(() => console.log('I'));
21});
22
23console.log('J');

Async/Await Pattern

Modern async/await syntax built on Promises. Learn how async functions suspend and resume execution through the Event Loop.

</>Demo Code
1console.log('Start');
2
3async function getData() {
4    console.log('1. Async function started');
5    
6    // await makes function pause here
7    const result = await Promise.resolve('Hello from Promise');
8    
9    console.log('2. After await:', result);
10    return 'Function complete';
11}
12
13// Call async function
14getData().then(data => {
15    console.log('3. Async function result:', data);
16});
17
18console.log('End - this runs before await resumes');

Complex Async/Await with Try-Catch-Finally

Advanced async/await example with multiple awaits, try-catch-finally blocks, and error handling. Master complex async patterns and exception handling.

</>Demo Code
1console.log('🚀 Start complex async/await');
2
3async function fetchUserData() {
4    console.log('1. 📡 Starting user data fetch...');
5    
6    try {
7        console.log('2. 🔍 Entering try block');
8        
9        // First await - simulate user API call
10        const userResponse = await Promise.resolve({
11            id: 123,
12            name: 'John Doe',
13            email: 'john@example.com'
14        });
15        
16        console.log('3. ✅ User data received:', userResponse.name);
17        
18        // Second await - simulate posts API call
19        const postsResponse = await Promise.resolve([
20            { id: 1, title: 'First Post', userId: userResponse.id },
21            { id: 2, title: 'Second Post', userId: userResponse.id }
22        ]);
23        
24        console.log('4. ✅ Posts data received:', postsResponse.length, 'posts');
25        
26        return {
27            user: userResponse,
28            posts: postsResponse,
29            status: 'success'
30        };
31        
32    } catch (error) {
33        console.log('5. ❌ Error caught:', error.message);
34        return {
35            user: null,
36            posts: [],
37            status: 'error',
38            error: error.message
39        };
40        
41    } finally {
42        console.log('6. 🧹 Finally block - cleaning up resources');
43        console.log('7. 📊 Logging analytics data...');
44    }
45}
46
47// Start the async operation
48console.log('8. 🎯 Calling fetchUserData...');
49
50fetchUserData().then(result => {
51    console.log('9. 🎉 Final result:', result.status);
52    console.log('10. 👤 User:', result.user.name);
53});
54
55console.log('11. ⚡ Synchronous code continues...');
56
57setTimeout(() => {
58    console.log('12. ⏰ Timer callback - this runs after all async operations');
59}, 0);
60
61console.log('13. 🏁 End of synchronous execution');