Fri Jun 06 2025
(Generated with ChatGPT)
JavaScript is single-threaded and uses the event loop to handle asynchronous tasks like network requests, timers, or I/O. Instead of blocking the thread, it schedules callbacks/promises to execute when the operation completes.
Common async patterns:
this
, and hoisting behavior.resolve
) or failure (reject
) of an async task..then()
method (custom or native).Promise.resolve({ then: (res) => res(42) }) // resolves to 42
promise.then(f1, f2).catch(f3)
promise.catch(f1).catch(f2).catch(f3)
Each .catch() handles previous errors; useful for:
async function returns a Promise.
await pauses execution until Promise resolves or rejects.
try {
const data = await fetchData();
} catch (err) {
console.error(err);
}
try/catch only captures errors inside an async function or awaited code.
async function* yields Promises
for await...of iterates over resolved values
async function* stream() {
yield await fetchPage(1);
}
for await (const page of stream()) {
console.log(page);
}
Use Cases:
Concurrency: Multiple tasks managed by time-sharing via event loop.
Parallelism: True multi-threading (via Web Workers).
JavaScript is concurrent, not parallel (except with Web Workers).
Happen when async callbacks access shared state in unpredictable order.
Example:
let counter = 0;
setTimeout(() => counter++, 100);
setTimeout(() => console.log(counter), 50); // prints 0
Use Promises/await to sequence operations
Avoid shared state or use mutex libraries
Too many concurrent Promises can overload system/network.
Solutions: Batching
for (let i = 0; i < arr.length; i += 10) {
await Promise.all(arr.slice(i, i + 10).map(task));
}
Concurrency limiters: p-limit, custom pools
Queues with delays/backoffs
Technique for fetching data without reloading the page.
Modern version:
fetch('/api/data')
.then(res => res.json())
.then(console.log)
API | Description |
---|---|
Promise.all([...]) | Resolves when all succeed or one fails |
Promise.race([...]) | Resolves/rejects as soon as one settles |
Promise.any([...]) | Resolves on first success, ignores failures |
Promise.allSettled([...]) | Waits for all, regardless of outcome |
Promise.reject([...]) | Returns a promise that is rejected |
Promise.resolve([...]) | Resolves a given value to a promise |
Promise.try([...]) | Wraps the result of any callback in a Promise |
AbortController | Used to cancel fetch() requests |
📌 Tip: Async programming = managing when code runs, not just what it does.