Understanding Asynchronous JavaScript

Step-by-step explanation of async concepts like Promises, Fetch, and Error Handling — by ZN Infotech Pvt. Ltd.

1️⃣ Asynchronous JavaScript

JavaScript runs on a single thread — meaning it executes one line at a time. However, it doesn’t block execution for slow tasks like API calls or timers. Instead, it uses an event loop to handle tasks asynchronously (in the background).

Key Concepts:

console.log("Start");
setTimeout(() => console.log("After 2 seconds"), 2000);
console.log("End");

// Output:
// Start
// End
// After 2 seconds
The setTimeout() function runs after 2 seconds, without blocking other lines of code.

2️⃣ Promises

A Promise in JavaScript represents a task that will complete in the future. It’s like saying, “I’ll give you the result later.” Promises make asynchronous code easier to manage than traditional callbacks.

Promise States:

const myPromise = new Promise((resolve, reject) => {
  const success = true;
  if (success) {
    resolve("✅ Data loaded successfully!");
  } else {
    reject("❌ Failed to load data");
  }
});

myPromise
  .then(result => console.log(result))
  .catch(error => console.error(error));
Promises help avoid callback hell — a situation where callbacks are nested deeply.

3️⃣ Fetch API

The Fetch API allows JavaScript to communicate with servers using HTTP requests (like GET, POST, PUT, DELETE). It returns a Promise, making it perfect for asynchronous data fetching.

fetch("https://jsonplaceholder.typicode.com/posts")
  .then(response => response.json())
  .then(data => console.log("Posts:", data))
  .catch(error => console.error("Error fetching data:", error));

Explanation:

Fetch is modern and replaces the old XMLHttpRequest for AJAX calls.

4️⃣ Async / Await

The async and await keywords simplify working with Promises. Instead of chaining multiple .then() blocks, you can write asynchronous code that looks synchronous.

async function getPosts() {
  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/posts");
    const posts = await response.json();
    console.log(posts);
  } catch (error) {
    console.error("Error:", error);
  }
}

getPosts();

Rules:

Async/Await makes asynchronous code cleaner, easier to read, and debug.

5️⃣ Error Handling in Asynchronous Code

Handling errors properly ensures your app doesn’t crash when something unexpected happens (like a failed API call or network issue).

async function fetchData() {
  try {
    const res = await fetch("https://wrong-url.com/data");
    if (!res.ok) {
      throw new Error("Network response failed");
    }
    const data = await res.json();
    console.log(data);
  } catch (err) {
    console.error("❌ Error occurred:", err.message);
  } finally {
    console.log("✅ Request finished (success or fail)");
  }
}

fetchData();

Best Practices:

Error handling is the difference between a stable app and one that breaks under small issues.