Skip to content

Asynchronous JavaScript

  • by

Asynchronous JavaScript allows tasks to be executed independently and non-blocking, enhancing the responsiveness and efficiency of web applications.

Traditionally, JavaScript code runs in a single-threaded environment, meaning that it can only execute one task at a time. However, this can cause problems when dealing with time-consuming operations, such as network requests or file I/O, as the execution of these tasks would block the main thread and make the entire program unresponsive.

It can be implemented using various syntax patterns and techniques. Here are some common ways to write asynchronous code:

Callbacks:

Callback functions are a common way of handling asynchronous operations in JavaScript. Instead of waiting for an operation to complete before moving on to the next line of code, a callback function is passed as an argument to an asynchronous function. Once the operation completes, the callback function is invoked to handle the result.

asyncFunction(arg1, arg2, (error, result) => {
  if (error) {
    // Handle error
  } else {
    // Handle result
  }
});

Promises:

Promises are a more recent addition to JavaScript and provide a more structured way of handling asynchronous operations. A promise represents the eventual completion or failure of an asynchronous operation and allows chaining of callbacks to handle the result. Promises can be in one of three states: pending, fulfilled, or rejected.

asyncFunction(arg1, arg2)
  .then(result => {
    // Handle result
  })
  .catch(error => {
    // Handle error
  });

Async/await:

Introduced in ES2017, the async/await syntax provides a more synchronous-looking way of writing asynchronous code. By using the async keyword before a function declaration, and the await keyword before an asynchronous operation, you can write code that appears to be sequential but actually allows other tasks to run concurrently.

async function myFunction() {
  try {
    const result = await asyncFunction(arg1, arg2);
    // Handle result
  } catch (error) {
    // Handle error
  }
}

Promise.all (for parallel execution):

Promise.all([asyncFunction1(), asyncFunction2(), asyncFunction3()])
  .then(results => {
    // Handle results
  })
  .catch(error => {
    // Handle error
  });

Event-driven programming (e.g., using event listeners):

eventEmitter.on('event', eventData => {
  // Handle event data
});

Asynchronous JavaScript examples

Simple example code that demonstrates asynchronous JavaScript using a callback:

// Asynchronous function with a callback
function fetchData(callback) {
  setTimeout(() => {
    const data = 'Async data';
    callback(null, data); // Pass the data to the callback
  }, 2000);
}

// Using the asynchronous function
console.log('Start');

fetchData((error, data) => {
  if (error) {
    console.error('Error:', error);
  } else {
    console.log('Received data:', data);
    // Perform further operations with the data
  }
});

console.log('End');

Output:

Asynchronous JavaScript

Another example using the Promises approach:

// Asynchronous function that returns a Promise
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = 'Async data';
      resolve(data); // Resolving the Promise with the data
    }, 2000);
  });
}

// Function that uses the asynchronous function
function processData() {
  console.log('Start');
  
  fetchData()
    .then(data => {
      console.log('Received data:', data);
      // Perform further operations with the data
    })
    .catch(error => {
      console.error('Error:', error);
    });

  console.log('End');
}

// Calling the function
processData();

Async/await for handling asynchronous JavaScript code:

// Asynchronous function that returns a Promise
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = 'Async data';
      resolve(data); // Resolving the Promise with the data
    }, 2000);
  });
}

// Using async/await to handle the asynchronous operation
async function processData() {
  console.log('Start');

  try {
    const data = await fetchData();
    console.log('Received data:', data);
    // Perform further operations with the data
  } catch (error) {
    console.error('Error:', error);
  }

  console.log('End');
}

// Calling the function
processData();

To write asynchronous JavaScript code, you can follow these general steps:

  1. Identify the asynchronous task: Determine which part of your code requires asynchronous handling. This could include network requests, file operations, timers, or any task that may have a delay or involve external resources.
  2. Choose an asynchronous mechanism: Select an appropriate asynchronous mechanism based on the JavaScript version and environment you are working with. Common options include callbacks, Promises, and async/await.
  3. Use callbacks:
    • Define a function that performs the asynchronous task and accepts a callback function as a parameter.
    • Inside the asynchronous function, perform the task and invoke the callback function with the result or an error if applicable.
  4. Use Promises:
    • Create a new Promise instance using the Promise constructor, passing a function (executor) with two parameters: resolve and reject.
    • Inside the executor function, perform the asynchronous task.
    • Call resolve with the result, if the task is successful, or call reject with an error if there is a failure.
  5. Use async/await:
    • Define an async function using the async keyword. This allows you to use the await keyword inside the function.
    • Use the await keyword before an asynchronous task to pause the function execution until the task is resolved or rejected.
    • Handle any potential errors using try-catch blocks.
  6. Handle the results or errors:
    • With callbacks, define a callback function that handles the result or error and invoke it from the asynchronous function.
    • With Promises, use the then method to handle the resolved value and the catch method to handle any errors.
    • With async/await, use try-catch blocks to handle errors and handle the resolved value directly in the function.

Remember to consider error handling and cleanup tasks, such as closing connections or releasing resources, depending on the specific asynchronous task.

Do comment if you have any doubts or suggestions on this JS tutorial.

Note: The All JS Examples codes are tested on the Firefox browser and the Chrome browser.

OS: Windows 10

Code: HTML 5 Version

Leave a Reply

Your email address will not be published. Required fields are marked *