why?

Mafuposts

Projects

Posts

[Gate] Javascript Asynchronous Programming

Fri Jun 06 2025

(Generated with ChatGPT)

Introduction to Asynchronous JS

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:

  • Callbacks
  • Promises
  • async/await
  • Event-driven programming

Event Loop and Execution Context

  • Event Loop manages the call stack and task queues.
  • Execution Context holds variable scope, this, and hoisting behavior.
  • Closures enable access to outer scopes in async operations.

Promises & Thenables

  • A Promise is an object representing future completion (resolve) or failure (reject) of an async task.
  • A Thenable is any object with a .then() method (custom or native).
  • Promises auto-resolve Thenables:
Promise.resolve({ then: (res) => res(42) }) // resolves to 42

Promise Composition

promise.then(f1, f2).catch(f3)
  • f1: handles resolved value
  • f2: handles initial rejection of promise
  • f3: catches errors thrown in f1, or rejections missed by f2
promise.catch(f1).catch(f2).catch(f3)

Each .catch() handles previous errors; useful for:

  • Retry logic
  • Logging
  • Graceful degradation

Async/Await

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 Iterators & Generators

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:

  • Streaming APIs
  • File readers
  • Throttled data consumption

Concurrency vs Parallelism

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).


Race Conditions

Happen when async callbacks access shared state in unpredictable order.

Example:

let counter = 0;
setTimeout(() => counter++, 100);
setTimeout(() => console.log(counter), 50); // prints 0

Prevention:

Use Promises/await to sequence operations

Avoid shared state or use mutex libraries


Controlling Concurrency Load

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


AJAX (Asynchronous JavaScript and XML)

Technique for fetching data without reloading the page.

Modern version:

fetch('/api/data')
  .then(res => res.json())
  .then(console.log)

Key APIs to Know

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.