Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

How AJAX Works

Step-by-Step AJAX Flow

Understanding the AJAX lifecycle helps you write better asynchronous code and debug issues more effectively. Here is the complete flow from user interaction to DOM update:

  1. User Event — The user triggers an action: a button click, a keypress in a search box, a form submission, or a scroll event.
  2. JavaScript Creates a Request — An event listener fires and JavaScript creates either an XMLHttpRequest object or calls the fetch() function.
  3. Request Sent to Server — The browser sends an HTTP request (GET, POST, etc.) to the server URL in the background. The page remains fully interactive.
  4. Server Processes the Request — The server-side code (PHP, Node.js, Python, etc.) receives the request, queries a database or performs logic, and prepares a response.
  5. Server Returns a Response — The server sends back data — typically JSON, but sometimes XML, HTML fragments, or plain text.
  6. JavaScript Receives the Response — A callback function, Promise .then(), or await expression receives the response data.
  7. DOM is Updated — JavaScript parses the response and updates only the relevant part of the page. No full reload occurs.
Complete AJAX Flow Example
// Step 1: User event — button click
document.getElementById('load-btn').addEventListener('click', function () {

  // Step 2: Show a loading indicator
  document.getElementById('result').textContent = 'Loading...';

  // Step 3: Create and send the request
  fetch('/api/data')
    // Step 6: Receive and parse the response
    .then(response => {
      if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
      return response.json();
    })
    // Step 7: Update the DOM
    .then(data => {
      document.getElementById('result').innerHTML =
        `<p>Received: ${data.message}</p>`;
    })
    .catch(error => {
      document.getElementById('result').textContent = `Error: ${error.message}`;
    });
});

Synchronous vs Asynchronous

Synchronous code executes line by line. Each line must finish before the next one starts. If a network request takes 3 seconds, the entire browser tab freezes for 3 seconds — the user cannot click, scroll, or type.

Asynchronous code allows the browser to continue executing other code while waiting for a slow operation (like a network request) to complete. When the operation finishes, a callback or Promise resolves and handles the result.

Synchronous vs Asynchronous Comparison
// ---- SYNCHRONOUS (blocks the thread) ----
// XMLHttpRequest with async=false — NEVER do this in production
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data', false); // false = synchronous
xhr.send();
// Browser is FROZEN here until the request completes
console.log('This runs only after the request finishes');

// ---- ASYNCHRONOUS (non-blocking) ----
// Using fetch — the browser stays responsive
console.log('1. Before fetch');

fetch('/api/data')
  .then(res => res.json())
  .then(data => {
    console.log('3. Data received:', data); // runs later
  });

console.log('2. After fetch call'); // runs immediately, before data arrives
// Output order: 1 → 2 → 3

The JavaScript Event Loop

JavaScript is single-threaded — it can only do one thing at a time. The event loop is the mechanism that makes asynchronous code possible without multiple threads.

  • Call Stack — where synchronous code executes, one frame at a time.
  • Web APIs — browser-provided APIs (like fetch, setTimeout) that handle async operations outside the call stack.
  • Callback Queue / Task Queue — completed async callbacks wait here to be pushed onto the call stack.
  • Microtask Queue — Promise callbacks (.then(), await) go here and are processed before the regular task queue.
  • Event Loop — continuously checks if the call stack is empty, then pushes the next task from the queue.
Event Loop Execution Order
console.log('A'); // synchronous — runs first

setTimeout(() => {
  console.log('B'); // macro-task — runs last
}, 0);

Promise.resolve().then(() => {
  console.log('C'); // micro-task — runs before setTimeout
});

console.log('D'); // synchronous — runs second

// Output: A → D → C → B
// Explanation:
// 1. Synchronous code runs: A, D
// 2. Microtask queue drains: C (Promise callbacks)
// 3. Macro-task queue: B (setTimeout)

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.