Open In App

How to chain asynchronous functions in JavaScript ?

Last Updated : 17 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

JavaScript is a single-threaded, asynchronous programming language. Thus, some time-consuming operations like I/O, accessing the database, network calls, etc. are performed asynchronously so that it does not interrupt things in the only JS thread. This can be done by asynchronous code like promises or async functions (which basically are cleaner promises). Asynchronous functions are cool, but the time of their execution is not certain, this sometimes creates a problem, when we have two async functions that depend on one another. 

Note: This article will be using ES2015+ features like async functions, arrow functions, etc. However, the same result is achievable using older ES features.

Example 1:To help us with that we have three async functions (black-box functions).

Javascript




<script>
  async function getUserData() {
      console.log('Fetching data');     
  }
  
  async function cleanUserData(userData) {
      console.log('Cleaning data');      
  }
  
  async function saveToDataBase(userData) {
      console.log('Saving to DB');     
  }
  const userData = getUserData();
  const cleanedData = cleanUserData(userData);
  saveToDataBase(cleanedData);
</script>


Output: These are asynchronous functions and their execution time is not always the same. So these functions can run in any possible order. The following is one possible output.

Cleaning data
Saving to DB
Fetching data

There are two ways to run these functions and enforce an order of function executions.

1.Using Promise’s  .then()

Javascript




<script>
async function getUserData() {
      console.log('Fetching data');     
  }
  
  async function cleanUserData(userData) {
      console.log('Cleaning data');      
  }
  
  async function saveToDataBase(userData) {
      console.log('Saving to DB');     
  }
  getUserData()
    .then((userData) => cleanUserData(userData))      
    .then((cleanedData) => saveToDataBase(cleanedData)) 
    .then(() => console.log('All work done'))        
 </script>


Output:

Fetching data
Cleaning data
Saving to DB
All work done

This is good and does the work, but sometimes it can create a callback hell, possibly ruining your mood when you see your code (just kidding).

2. Using async / await:

There is a cleaner way to do the same thing, waiting for a function to complete its execution using the await keyword. The await() works only inside the async() function. So, we need to wrap these inside a wrapper function.

Javascript




<script>
  async function getUserData() {
      console.log('Fetching data');     
  }
  
  async function cleanUserData(userData) {
      console.log('Cleaning data');      
  }
  
  async function saveToDataBase(userData) {
      console.log('Saving to DB');     
  }
  async function cleanAndSaveUserData() {
    const userData = await getUserData();
    const cleanedData = await cleanUserData(userData);
    await saveToDataBase(cleanedData);
      
    console.log('All work done');
  }
  
  cleanAndSaveUserData(); // does all the work
  
</script>


Output:

Fetching data
Cleaning data
Saving to DB
All work done

Note: This article does not cover error handling in chained async() functions for simplicity.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads