Skip to main content

Asynchronous JavaScript

JavaScript is Single-Threaded, which means it can only do one thing at a time. Normally, it runs code line-by-line (Synchronous). But some tasks—like getting data from an API—take time. If JS waited for those tasks, your website would "freeze."


Asynchronous


Asynchronous (Async) code allows JavaScript to start a long task, move on to other things, and come back to finish the task once it's done.

1. The "Waiting" Problem

Imagine you ask a server for a list of users. If the internet is slow, the code stops.

  • Synchronous: Line 1 → Line 2 (Wait 5s) → Line 3.
  • Asynchronous: Line 1 → Line 2 (Start task) → Line 3 → (Task finishes later).

2. Promises: A Deal for the Future

A Promise is exactly what it sounds like. It’s an object that represents a value that isn't available yet, but will be eventually.

A Promise has three states:

  1. Pending: Still waiting (water is boiling).
  2. Fulfilled: Success! (water is boiled).
  3. Rejected: Something went wrong (the stove broke).
const myPromise = new Promise((resolve, reject) => {
let success = true;
if (success) {
resolve("Data received! ✅");
} else {
reject("Error: Server down ❌");
}
});

myPromise
.then((data) => console.log(data)) // Runs if resolved
.catch((err) => console.log(err)); // Runs if rejected

3. Async / Await (The Modern Way)

While .then() is great, modern developers prefer Async/Await. It makes asynchronous code look and feel like "normal" line-by-line code.

  • async: Tells JS this function will handle asynchronous tasks.
  • await: Tells JS to "pause" inside the function until the promise is finished.
async function getUserData() {
console.log("Fetching...");

// Imagine this takes 2 seconds
let response = await fetch('https://api.example.com/user');
let data = await response.json();

console.log(data);
}

getUserData();

4. Handling Errors with Try/Catch

When using async/await, we use a try...catch block to handle any "Rejections" (errors).

async function safeFetch() {
try {
let response = await fetch('https://invalid-url.com');
let data = await response.json();
} catch (error) {
console.log("Something went wrong: " + error);
}
}

5. Real-World Example: Fetching an API

Let's fetch a random quote from the internet and display it.

const getQuote = async () => {
const response = await fetch('https://api.quotable.io/random');
const data = await response.json();

console.log(`${data.content}${data.author}`);
};

getQuote();

Practice: The "Delayed Greeting"

Try this in your script.js to understand the timing:

  1. Create an async function.
  2. Use a setTimeout wrapped in a promise to wait for 3 seconds.
  3. Log "Hello after 3 seconds!" to the console.
const delay = (ms) => new Promise(res => setTimeout(res, ms));

async function welcome() {
console.log("Starting timer...");
await delay(3000); // Wait 3 seconds
console.log("Hello from CodeHarborHub!");
}

welcome();
Why this matters?

In a Full-Stack application, almost everything involves "waiting": logging in, fetching posts, uploading photos, or saving a profile. Mastering Async/Await is what makes your apps feel fast and professional.