April 14, 2025

Asynchronous JavaScript

A random blog on Asynchronous JS copied from chatgpt

thumbnail

Pitch Details

🚀 Understanding Asynchronous JavaScript: Callbacks, Promises, and Async/Await

JavaScript is single-threaded, meaning it executes code one line at a time. But if it’s single-threaded, how does it handle things like API calls, timers, or user interactions without freezing the page?

The answer lies in asynchronous JavaScript. Let’s dive into how JavaScript handles async operations and how you can use it effectively in your projects.


🔁 The Problem with Synchronous Code

function fetchData() {
  const data = fetch('https://api.example.com');
  console.log(data);
}

fetchData();

The code above tries to fetch data synchronously, which doesn’t work because the response isn’t instant. JavaScript would log Promise { <pending> } or even throw an error.


⏳ JavaScript's Event Loop: The Hero

JavaScript offloads tasks like network requests to the Web APIs (browser) and continues executing other code. Once the async task is done, the result is pushed to the callback queue, which the event loop picks up when the call stack is clear.

This is why setTimeout, fetch, or addEventListener don’t block the execution.


🧱 Asynchronous Building Blocks

1. Callbacks

function getData(callback) {
  setTimeout(() => {
    callback("Here's your data");
  }, 1000);
}

getData((data) => {
  console.log(data);
});

Pros: Simple to understand
Cons: Leads to callback hell 😩

login(user, () => {
  getUserData(user, () => {
    fetchSettings(user, () => {
      // 😵
    });
  });
});

2. Promises

A Promise represents a value that may be available now, later, or never.

const promise = new Promise((resolve, reject) => {
  const success = true;
  setTimeout(() => {
    success ? resolve("Success!") : reject("Error!");
  }, 1000);
});

promise
  .then((res) => console.log(res))
  .catch((err) => console.error(err));

Pros: Cleaner chaining
Cons: Still a bit hard to read in complex flows


3. Async/Await (Syntactic Sugar)

async function fetchData() {
  try {
    const res = await fetch('https://api.example.com');
    const data = await res.json();
    console.log(data);
  } catch (error) {
    console.error('Error:', error);
  }
}

Pros: Reads like synchronous code
Cons: Still needs error handling and doesn’t make async operations synchronous


🎯 When to Use What?

  • Use callbacks for simple things like setTimeout
  • Use promises or async/await for API calls or complex chains
  • In frameworks like React, async/await is great for useEffect calls

🧠 Bonus: Async in React (with useEffect)

import { useEffect, useState } from 'react';

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    async function loadData() {
      const res = await fetch('/api/data');
      const json = await res.json();
      setData(json);
    }

    loadData();
  }, []);

  return <div>{data ? data.message : 'Loading...'}</div>;
}

⚡ Final Thoughts

Mastering asynchronous JavaScript is a game-changer for modern frontend development. Whether you're fetching data in React, setting up timers, or handling user input, knowing how async works will make your code more powerful and bug-free.

🧠 Tip: Always wrap your async functions in try/catch to handle errors gracefully!


Let me know if you'd like this converted to Markdown, or posted on platforms like Dev.to, Medium, or your own blog site. I can also make a version for LinkedIn if you want to share it with potential recruiters.