JavaScript Fundamentals

Asynchronous JavaScript

Understanding Asynchronous JavaScript

Asynchronous programming is crucial for handling operations that might take some time to complete, such as fetching data from a server or reading files. JavaScript provides several ways to work with asynchronous code, from callbacks to modern async/await syntax.

Callbacks

// Callback Example
function fetchData(callback) {
  setTimeout(() => {
    const data = { id: 1, name: 'John' };
    callback(data);
  }, 1000);
}

fetchData((result) => {
  console.log(result); // { id: 1, name: 'John' }
});

// Callback Hell Example (What to Avoid)
fetchUser(userId, (user) => {
  fetchPosts(user.id, (posts) => {
    fetchComments(posts[0].id, (comments) => {
      console.log(comments);
    });
  });
});

Promises

// Promise Example
function fetchUser(id) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const user = { id: id, name: 'John' };
      resolve(user);
      // If error: reject(new Error('User not found'));
    }, 1000);
  });
}

// Using Promises
fetchUser(1)
  .then(user => console.log(user))
  .catch(error => console.error(error));

// Promise Chaining
fetchUser(1)
  .then(user => fetchPosts(user.id))
  .then(posts => fetchComments(posts[0].id))
  .then(comments => console.log(comments))
  .catch(error => console.error(error));

Async/Await

// Async/Await Example
async function getUserData(id) {
  try {
    const user = await fetchUser(id);
    const posts = await fetchPosts(user.id);
    const comments = await fetchComments(posts[0].id);
    return { user, posts, comments };
  } catch (error) {
    console.error('Error:', error);
  }
}

// Using Async Function
async function init() {
  const data = await getUserData(1);
  console.log(data);
}

// Parallel Requests
async function getMultipleUsers() {
  const userPromises = [
    fetchUser(1),
    fetchUser(2),
    fetchUser(3)
  ];
  const users = await Promise.all(userPromises);
  return users;
}

Fetch API

// Fetch API Example
fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

// Async/Await with Fetch
async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error:', error);
  }
}