Asynchronous JavaScript

Section 2: Asynchronous JavaScript

Lesson 1: Introduction to Callbacks

Callbacks are functions passed as arguments to other functions, allowing you to control the flow of your code. They are essential for handling asynchronous operations.

1.1 Understanding the Basics of Callback Functions 

// Example of a callback function

function fetchData(callback) {

  setTimeout(() => {

    const data = 'Async data';

    callback(data);

  }, 1000);

}


// Using a callback

fetchData(result => {

  console.log(result); // Output: Async data

});

1.2 Handling Asynchronous Operations with Callbacks 

// Simulating an asynchronous operation with callbacks

function downloadFile(url, onSuccess, onError) {

  const success = Math.random() > 0.5;


  setTimeout(() => {

    if (success) {

      onSuccess(`Downloaded: ${url}`);

    } else {

      onError('Download failed');

    }

  }, 1000);

}


// Using the downloadFile function with callbacks

downloadFile(

  'https://example.com/file.zip',

  result => console.log(result),

  error => console.error(error)

);


Lesson 2: Promises and Promise Chaining

Promises provide a cleaner way to handle asynchronous code compared to callbacks. They represent the eventual completion or failure of an asynchronous operation.

2.1 Overview of Promises 

// Creating a Promise

const fetchData = new Promise((resolve, reject) => {

  setTimeout(() => {

    const data = 'Async data';

    resolve(data);

  }, 1000);

});


// Using a Promise

fetchData.then(result => {

  console.log(result); // Output: Async data

});

2.2 Chaining Multiple Promises for Sequential Execution

// Chaining promises

const fetchData = () => {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const data = 'Async data';

      resolve(data);

    }, 1000);

  });

};


fetchData()

  .then(result => {

    console.log(result); // Output: Async data

    return 'Additional data';

  })

  .then(additionalData => {

    console.log(additionalData); // Output: Additional data

  });


Lesson 3: Introduction to Async/Await

Async/await is a modern JavaScript feature that simplifies asynchronous code, making it look and behave more like synchronous code.

3.1 Simplifying Asynchronous Code with Async/Await Syntax

 

// Using async/await

const fetchData = () => {

  return new Promise((resolve) => {

    setTimeout(() => {

      const data = 'Async data';

      resolve(data);

    }, 1000);

  });

};


const fetchDataWithAsyncAwait = async () => {

  const result = await fetchData();

  console.log(result); // Output: Async data

};


fetchDataWithAsyncAwait();

3.2 Error Handling in Async Functions 

// Handling errors with async/await

const fetchData = () => {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      const success = Math.random() > 0.5;

      if (success) {

        resolve('Async data');

      } else {

        reject('Async data error');

      }

    }, 1000);

  });

};


const fetchDataWithAsyncAwait = async () => {

  try {

    const result = await fetchData();

    console.log(result);

  } catch (error) {

    console.error(error);

  }

};


fetchDataWithAsyncAwait();

In the next section, we'll explore the concept of JavaScript modules and how they enhance code organization and maintainability.