Advance JavaScript (DOM, BOM, Web API) / Asynchronous JavaScript

Callback Examples

🔴 ISSUE: Returning data before async work finishes

function getUsers() {
  let users = [];
  setTimeout(() => {
    users = [
      { username: 'john', email: 'john@test.com' },
      { username: 'jane', email: 'jane@test.com' },
    ];
  }, 1000);
  return users;
}

function findUser(username) {
  const users = getUsers();
  const user = users.find((user) => user.username === username);
	console.log(user);
}

findUser('john')
  • findUser('john') calls getUsers().

  • getUsers() creates an empty array and starts a setTimeout.

  • JavaScript does NOT wait for the timeout.

  • getUsers() immediately returns the empty array [].

  • Back in findUser, users is [], so .find() returns undefined.

  • The setTimeout updates the users after 1 second, but by then the function already finished.

undefined

✅ SOLUTION: Use Callback

function getUsers(callback) {
  setTimeout(() => {
    callback([
      { username: 'john', email: 'john@test.com' },
      { username: 'jane', email: 'jane@test.com' },
    ]);
  }, 1000);
}

function findUser(username, callback) {
  getUsers((users) => {
    const user = users.find((user) => user.username === username);
    callback(user);
  });
}

findUser('john', console.log);
  • findUser('john', console.log) is called.

  • Inside findUser, it calls getUsers.

  • getUsers uses setTimeout and after 1 second it runs the callback and sends the users list.

  • Once users arrive, findUser searches for "john" in the list.

  • The found user is passed to the callback → which is console.log.

  • So the user object gets printed.

{ username: 'john', email: 'john@test.com' }

🎯 Practical Example with Fetch API

❌ Wrong Approach (returns empty array)

function getUsers() {
  let users = [];
  fetch("<https://jsonplaceholder.typicode.com/users>")
    .then((res) => res)
    .then((data) => users.push(data));
  console.log(users);
}

fetch() is async → data arrives later → returns [].


✅ Correct Solution (Using Callback)

function getUsers(callback) {
  fetch("<https://jsonplaceholder.typicode.com/users>")
    .then((res) => res.json())
    .then((data) => callback(data));
}

// Usage
getUsers((users) => {
  console.log(users);
});
  • fetch() is asynchronous, so we can't return the data directly.

  • Instead, we wait for the fetch to finish and then call the callback with the user data.

  • The callback receives the actual users and prints them.