Docs
README
Module 16: Advanced Asynchronous JavaScript
Master advanced asynchronous programming patterns for building robust, scalable, and performant JavaScript applications.
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ADVANCED ASYNC JAVASCRIPT ā ā
ā ā ā ā
ā ā "Concurrency is about dealing with lots of things at once. ā ā
ā ā Parallelism is about doing lots of things at once." ā ā
ā ā - Rob Pike ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā āāāāāāāāāāāāāāā āāāāāāāāāāāāāāā āāāāāāāāāāāāāāā āāāāāāāāāāāāāāā ā
ā ā COMBINE ā ā HANDLE ā ā PATTERN ā ā CANCEL ā ā
ā ā āāāāāāāāā ā ā āāāāāāāāā ā ā āāāāāāāāā ā ā āāāāāāāāā ā ā
ā ā Promise.all ā ā Retries ā ā Streams ā ā Abort ā ā
ā ā .race ā ā Timeouts ā ā Iteration ā ā Controller ā ā
ā ā .any ā ā Recovery ā ā Workers ā ā Cleanup ā ā
ā āāāāāāāāāāāāāāā āāāāāāāāāāāāāāā āāāāāāāāāāāāāāā āāāāāāāāāāāāāāā ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
š Module Overview
This module takes you beyond basic Promises and async/await into the realm of production-grade async programming. You'll learn to handle complex scenarios like parallel execution, graceful error recovery, and cancellation.
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā FROM BASIC TO ADVANCED ASYNC ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Basic: Advanced: ā
ā āāāāāā āāāāāāāāā ā
ā ā
ā const data = await fetch(url); const results = await Promise.all([ ā
ā fetch(url1), ā
ā fetch(url2), ā
ā fetch(url3) ā
ā ]); ā
ā ā
ā try { async function fetchWithRetry(url) { ā
ā await doSomething(); for (let i = 0; i < 3; i++) { ā
ā } catch (err) { try { ā
ā console.error(err); return await fetch(url); ā
ā } } catch (e) { ā
ā await delay(1000 * 2 ** i); ā
ā } ā
ā } ā
ā throw new Error('Failed'); ā
ā } ā
ā ā
ā Sequential: Parallel: ā
ā const a = await fetch(url1); const [a, b, c] = await Promise.all([ ā
ā const b = await fetch(url2); fetch(url1), ā
ā const c = await fetch(url3); fetch(url2), ā
ā // Takes: 3 Ć time fetch(url3) ā
ā ]); ā
ā // Takes: max(time1, time2, time3) ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
šÆ Learning Objectives
By the end of this module, you will be able to:
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā SKILL PROGRESSION ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Level 1: Parallel Execution ā
ā āāā Execute multiple async operations in parallel ā
ā āāā Choose the right Promise combinator for each situation ā
ā āāā Understand settle vs reject behavior ā
ā ā
ā Level 2: Error Management ā
ā āāā Handle complex error scenarios ā
ā āāā Implement retry logic with backoff ā
ā āāā Design graceful degradation strategies ā
ā ā
ā Level 3: Advanced Patterns ā
ā āāā Implement debouncing and throttling ā
ā āāā Build timeout mechanisms ā
ā āāā Create async queues and pools ā
ā ā
ā Level 4: Production Readiness ā
ā āāā Create cancellable async operations ā
ā āāā Stream data with async iterators ā
ā āāā Build real-world async utilities ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
š Prerequisites
- ā¢Module 15: Asynchronous JavaScript - Promises, async/await
- ā¢Module 12: Execution Context - Event loop understanding
- ā¢Module 13: Modern JavaScript - Generators basics
š Sections
16.1 Promise Combinators
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā PROMISE COMBINATORS ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Promise.all([p1, p2, p3]) ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā p1: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā ā ā
ā ā p2: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā ā ā
ā ā p3: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā ā ā
ā ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā ā
ā ā Returns: [r1, r2, r3] ā ā
ā ā If ANY fails: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā (rejects immediately)ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā Promise.allSettled([p1, p2, p3]) ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā p1: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā ā ā
ā ā p2: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā (no problem!)ā ā
ā ā p3: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā ā ā
ā ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā ā
ā ā Returns: [{status, value/reason}, ...] ā ā
ā ā ALWAYS resolves, never rejects ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā Promise.race([p1, p2, p3]) ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā p1: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ (too slow) ā ā
ā ā p2: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā WINNER! ā ā
ā ā p3: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ (too slow) ā ā
ā ā āāāāāāāāāāāŗ ā ā
ā ā ā Returns FIRST to settle (fulfill OR reject) ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā Promise.any([p1, p2, p3]) ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā p1: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā (ignored) ā ā
ā ā p2: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā WINNER! ā ā
ā ā p3: āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāŗ ā (ignored) ā ā
ā ā āāāāāāāāāāāāāāāāāāāŗ ā ā
ā ā ā Returns FIRST to FULFILL (ignores rejections) ā ā
ā ā ā ā
ā ā If ALL fail: ā AggregateError (collection of all errors) ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
- ā¢Promise.all() - Parallel execution, fail-fast
- ā¢Promise.allSettled() - Get all results regardless of failures
- ā¢Promise.race() - First to settle wins
- ā¢Promise.any() - First to fulfill wins
16.2 Advanced Error Handling
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ERROR HANDLING STRATEGIES ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Error Propagation: ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā async function level3() { ā ā
ā ā throw new Error('Deep error'); āāā ā ā
ā ā } ā ā ā
ā ā ā propagates up ā ā
ā ā async function level2() { ā ā ā
ā ā await level3(); āāāāāāāāāāāāāāāāāāā ā ā
ā ā } āāā ā ā
ā ā ā propagates up ā ā
ā ā async function level1() { ā ā
ā ā try { ā ā ā
ā ā await level2(); āā ā ā
ā ā } catch (err) { ā ā
ā ā console.log('Caught:', err); āāā Handled here! ā ā
ā ā } ā ā
ā ā } ā ā
ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā Recovery Patterns: ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā async function fetchWithFallback() { ā ā
ā ā try { ā ā
ā ā return await primarySource(); // Try primary ā ā
ā ā } catch { ā ā
ā ā return await backupSource(); // Fall back ā ā
ā ā } ā ā
ā ā } ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
- ā¢Error propagation - How errors bubble through async code
- ā¢Global error handlers - window.onerror, unhandledrejection
- ā¢Error recovery patterns - Fallbacks and retries
- ā¢Graceful degradation - Partial success handling
16.3 Async Patterns
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ASYNC PATTERNS ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Retry with Exponential Backoff: ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā Attempt 1: āā ā ā ā ā
ā ā āāā Wait 1 second ā ā
ā ā Attempt 2: āāāā ā ā ā ā
ā ā āāā Wait 2 seconds ā ā
ā ā Attempt 3: āāāāāāāā ā ā ā ā
ā ā āāā Wait 4 seconds ā ā
ā ā Attempt 4: āāāāāāāāāāāāāāāā ā ā Success! ā ā
ā ā ā ā
ā ā delay = baseDelay * (2 ^ attemptNumber) ā ā
ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā Timeout Pattern: ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā function timeout(promise, ms) { ā ā
ā ā const timer = new Promise((_, reject) => { ā ā
ā ā setTimeout(() => reject(new Error('Timeout')), ms); ā ā
ā ā }); ā ā
ā ā return Promise.race([promise, timer]); ā ā
ā ā } ā ā
ā ā ā ā
ā ā await timeout(fetch(url), 5000); // 5 second timeout ā ā
ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā Throttle vs Debounce: ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā Events: ā āā ā āāāā ā ā āāā ā ā
ā ā ā ā
ā ā Throttle: ā ā ā ā (At most once per interval) ā ā
ā ā ā ā
ā ā Debounce: ā (Only after silence) ā ā
ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
- ā¢Retry with exponential backoff - Smart failure recovery
- ā¢Timeout handling - Don't wait forever
- ā¢Debouncing and throttling - Rate limiting
- ā¢Sequential vs parallel execution - When to use each
16.4 Web Workers
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā WEB WORKERS ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Main Thread Worker Thread ā
ā āāāāāāāāāāāāā āāāāāāāāāāāāā ā
ā āāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāā ā
ā ā ā postMessage ā ā ā
ā ā UI + ā āāāāāāāāāāāāāāāāāāāŗ ā Heavy ā ā
ā ā Events ā ā Computation ā ā
ā ā ā āāāāāāāāāāāāāāāāāāā ā ā ā
ā ā ā postMessage ā ā ā
ā āāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā UI stays ā CPU-intensive ā
ā ā responsive! ā work here ā
ā ā
ā // main.js // worker.js ā
ā const worker = new Worker( self.onmessage = (e) => { ā
ā 'worker.js' const result = heavyCalc(e.data); ā
ā ); self.postMessage(result); ā
ā worker.postMessage(data); }; ā
ā worker.onmessage = (e) => { ā
ā console.log(e.data); ā
ā }; ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
- ā¢Dedicated Workers - Background threads
- ā¢Shared Workers - Shared between tabs
- ā¢Service Workers - Offline and caching
- ā¢Worker communication - postMessage, Transferable
16.5 Async Iterators & Streams
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ASYNC ITERATION ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Async Generator: ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā async function* fetchPages(url) { ā ā
ā ā let page = 1; ā ā
ā ā while (true) { ā ā
ā ā const response = await fetch(`${url}?page=${page}`); ā ā
ā ā const data = await response.json(); ā ā
ā ā if (data.length === 0) break; ā ā
ā ā yield data; āāā Yield and pause ā ā
ā ā page++; ā ā
ā ā } ā ā
ā ā } ā ā
ā ā ā ā
ā ā // Consuming ā ā
ā ā for await (const page of fetchPages('/api/items')) { ā ā
ā ā console.log(page); āāā Resume and get next ā ā
ā ā } ā ā
ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā Stream Flow: ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā Source āāāŗ [chunk] āāāŗ [chunk] āāāŗ [chunk] āāāŗ Consumer ā ā
ā ā ā ā ā ā ā
ā ā āāāāāāā¬āāāāāā“āāāāāā¬āāāāāā ā ā
ā ā ā ā ā ā
ā ā Transform Transform ā ā
ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
- ā¢for await...of loops - Iterate over async data
- ā¢Async generators - yield with await
- ā¢Streaming data - Process large data incrementally
- ā¢Pagination patterns - Lazy loading data
16.6 Advanced Error Handling
More patterns for robust error handling in async code.
16.7 AbortController & Cancellation
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā CANCELLATION ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā AbortController Flow: ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā ā ā
ā ā const controller = new AbortController(); ā ā
ā ā const signal = controller.signal; ā ā
ā ā ā ā
ā ā // Start operation ā ā
ā ā fetch(url, { signal }) ā ā
ā ā .then(response => response.json()) ā ā
ā ā .catch(err => { ā ā
ā ā if (err.name === 'AbortError') { ā ā
ā ā console.log('Cancelled!'); ā ā
ā ā } ā ā
ā ā }); ā ā
ā ā ā ā
ā ā // Later: cancel the operation ā ā
ā ā controller.abort(); ā ā
ā ā ā ā ā
ā ā ā¼ ā ā
ā ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā ā
ā ā ā signal.aborted = true ā ā ā
ā ā ā 'abort' event fires ā ā ā
ā ā ā fetch() rejects ā ā ā
ā ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā ā
ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
ā Use Cases: ā
ā āāā Cancel fetch on component unmount ā
ā āāā Cancel previous search when user types new query ā
ā āāā Timeout with cancellation ā
ā āāā User-initiated cancel buttons ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
- ā¢AbortController API - Modern cancellation
- ā¢Cancellable promises - Wrapping operations
- ā¢Cleanup on cancellation - Resource management
- ā¢Timeout with cancellation - Time-limited operations
š Key Concepts Summary
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā COMBINATOR QUICK REFERENCE ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Combinator ā Resolves When ā Rejects When ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā Promise.all ā ALL fulfill ā ANY rejects (fail-fast) ā
ā Promise.allSettled ā ALL settle ā NEVER rejects ā
ā Promise.race ā FIRST settles ā FIRST rejects (if first) ā
ā Promise.any ā FIRST fulfills ā ALL reject (AggregateError) ā
ā ā
ā Pattern ā Use Case ā Example ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā Retry + backoff ā Network failures ā API calls, webhooks ā
ā Timeout ā Prevent hanging ā fetch(), external services ā
ā Debounce ā User input ā Search, autocomplete ā
ā Throttle ā Frequent events ā Scroll, resize handlers ā
ā Cancellation ā User navigation ā SPA route changes, cleanup ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
š” Common Patterns
Parallel with Timeout
async function fetchWithTimeout(url, timeout = 5000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, { signal: controller.signal });
return await response.json();
} finally {
clearTimeout(timeoutId);
}
}
Retry with Exponential Backoff
async function fetchWithRetry(url, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fetch(url);
} catch (err) {
if (i === maxRetries - 1) throw err;
await new Promise((r) => setTimeout(r, 1000 * Math.pow(2, i)));
}
}
}
Concurrent with Limit
async function mapWithLimit(items, limit, fn) {
const results = [];
const executing = new Set();
for (const item of items) {
const promise = fn(item).then((result) => {
executing.delete(promise);
return result;
});
executing.add(promise);
results.push(promise);
if (executing.size >= limit) {
await Promise.race(executing);
}
}
return Promise.all(results);
}
š Section Files
| Section | Topic | Key Files |
|---|---|---|
| 16.1 | Promise Combinators | 01-promise-all.js, 02-race-any.js |
| 16.2 | Error Handling | 01-error-propagation.js, 02-recovery.js |
| 16.3 | Async Patterns | 01-retry.js, 02-debounce-throttle.js |
| 16.4 | Web Workers | 01-dedicated-worker.js, worker.js |
| 16.5 | Async Iterators | 01-async-generators.js, 02-streams.js |
| 16.6 | Advanced Errors | 01-global-handlers.js, 02-aggregation.js |
| 16.7 | Cancellation | 01-abort-controller.js, 02-timeout.js |
ā ļø Common Pitfalls
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ASYNC PITFALLS TO AVOID ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā ā Ignoring Promise.race cleanup ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā Promise.race([fetch(url), timeout(5000)]); ā
ā // ā ļø If timeout wins, fetch keeps running! ā
ā // ā
Use AbortController for proper cleanup ā
ā ā
ā ā Sequential when parallel is possible ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā const a = await fetch(url1); // Waits ā
ā const b = await fetch(url2); // Then waits ā
ā // ā
const [a, b] = await Promise.all([fetch(url1), fetch(url2)]); ā
ā ā
ā ā Swallowing errors ā
ā āāāāāāāāāāāāāāāāāāāāāāāā ā
ā promise.catch(() => {}); // Silent failure! ā
ā // ā
Log, report, or handle meaningfully ā
ā ā
ā ā Not handling partial failures ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā await Promise.all(urls.map(fetch)); // One failure = all fail ā
ā // ā
Use Promise.allSettled for partial success ā
ā ā
ā ā Retry without backoff ā
ā āāāāāāāāāāāāāāāāāāāāāāā ā
ā while (true) { try { await fetch(); } catch { continue; } } ā
ā // ā ļø Hammers server, uses resources ā
ā // ā
Add exponential backoff + max retries ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
š Related Modules
- ā¢Previous: Module 15 - Asynchronous JavaScript
- ā¢Next: Module 17 - DOM Manipulation
- ā¢Related: Module 13.5 - Generators
šÆ Learning Path
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā RECOMMENDED ORDER ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā Week 1: Combinators ā
ā āāā Master Promise.all and Promise.race ā
ā āāā Learn Promise.allSettled for resilience ā
ā āāā Understand Promise.any for fallbacks ā
ā ā
ā Week 2: Error Handling & Patterns ā
ā āāā Implement retry with backoff ā
ā āāā Build timeout utilities ā
ā āāā Practice debounce and throttle ā
ā ā
ā Week 3: Advanced ā
ā āāā Learn async generators ā
ā āāā Implement pagination with for await...of ā
ā āāā Master AbortController for cancellation ā
ā ā
ā Week 4: Real-World ā
ā āāā Build a fetch wrapper with all features ā
ā āāā Create an async queue ā
ā āāā Implement caching with async ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā