Back to JavaScript Notes
Topic #412

Asynchronous Programming

By the end of this lesson, you will be able to explain why long JavaScript tasks block the browser main thread and use asynchronous scheduling such as setTimeout(() => {}, 0) to keep the page responsive.

What it is

Asynchronous programming is a way to schedule work so it happens later, after the current JavaScript task finishes. In the browser, JavaScript runs on the main thread, which also handles clicks, input, animations, and rendering. If one function runs for too long, the browser cannot process those other duties until the function returns.

The mental model is a single worker with a to-do list. The current task must finish before the worker can pick up the next queued task. setTimeout does not pause the current task; it adds a callback to the task queue. Related terms include the event loop, call stack, task queue, microtasks, promises, and long tasks.

Why it matters

  • Keeps buttons, scrolling, and typing responsive.
  • Prevents the browser from showing “page not responding” warnings.
  • Lets animations and timers continue while background work is scheduled.
  • Makes it possible to process large data sets in small chunks.
  • Improves perceived performance by showing progress instead of freezing.

Syntax or steps

The smallest useful pattern is to move the blocking part into a callback:

setTimeout(() => {
  // work that should happen after the current task
}, 0);

Steps:

  1. Do quick setup work synchronously, such as updating the UI.
  2. Call setTimeout with a callback and a delay of 0.
  3. Let the current function return so the browser can handle events and rendering.
  4. The browser later runs the callback when the call stack is empty.

Example

const items = Array.from({ length: 100000 }, (_, i) => i);
let index = 0;

function processChunk() {
  const start = Date.now();

  while (index < items.length && Date.now() - start < 10) {
    items[index] = items[index] * 2;
    index++;
  }

  if (index < items.length) {
    setTimeout(processChunk, 0);
  } else {
    console.log("Done processing all items.");
  }
}

processChunk();

Part by part:

  • Array.from creates a large array to simulate real work.
  • processChunk does only about 10 milliseconds of work per call.
  • The while loop stops when time runs out or all items are processed.
  • setTimeout(processChunk, 0) schedules the next chunk after the current task ends.
  • Because each chunk returns quickly, the browser can handle clicks, scrolling, and rendering between chunks.

Common mistakes

  • Thinking setTimeout(() => {}, 0) runs immediately. It runs after the current task finishes, so a long synchronous loop before it still blocks the page.
  • Using async and await around a CPU-heavy loop and expecting it to become non-blocking. The loop still runs on the main thread unless work is chunked or moved to a worker.
  • Forgetting to update progress or finish state when using repeated setTimeout calls.
  • Choosing too large a chunk size. If each chunk takes hundreds of milliseconds, the UI still freezes.

When to use it

Use setTimeout chunking when you need to split main-thread work into smaller tasks. Use a Web Worker when the work is CPU-bound and can run off the main thread. Use requestAnimationFrame when the work is tied to visual updates.

TechniqueBest forLimitation
setTimeout(() => {}, 0)Yielding briefly to the browser and processing data in chunks.Still runs on the main thread.
Web WorkerHeavy calculations that should not block the UI.Cannot directly access the DOM.
requestAnimationFrameAnimation and visual updates.Not ideal for arbitrary background work.

Practice

Guided exercise: Write code that logs "before", schedules setTimeout(() => console.log("after timeout"), 0), then runs a loop that takes about one second, and finally logs "after loop". Predict the order.

Expected output: before, after loop, after timeout.

Challenge: Process an array of 50,000 numbers by adding 1 to each item in chunks of 5,000 using setTimeout. Hint: keep an index variable and schedule the next chunk until index reaches the array length.

Quick check

Question: Why does setTimeout(() => {}, 0) not make a long synchronous loop non-blocking?

Answer: Because the loop is part of the current task. The timeout callback is queued and cannot run until the loop finishes and the call stack is empty.

Summary

Asynchronous scheduling gives the browser a chance to handle user interaction and rendering between pieces of work. setTimeout(() => {}, 0) is a simple way to yield, but it does not magically move work off the main thread.

Want to go beyond the notes?

Join Coding Now Tech Institute's JavaScript course — live mentorship, real projects, and 100% placement support.

Enroll Now — Free Demo Available

Asynchronous Programming – FAQs

Quick answers about learning Asynchronous Programming in JavaScript.

This free note from Coding Now Tech Institute explains Asynchronous Programming in JavaScript — concept, syntax and worked code examples you can copy, run and revise before interviews.
Yes. Every JavaScript topic on Coding Now Tech Institute, including Asynchronous Programming, is 100% free with no signup required.
With focused practice, most students grasp Asynchronous Programming in 1–3 days from these notes; pairing it with Coding Now Tech Institute's mentor-led course takes you to job-ready depth faster.
Use the code examples in this note, then ask doubts for free on the Coding Now Tech Institute Community (/community) — expert instructors answer within 24 hours.
Call NowEnroll Now