DEV Community

Shameel Uddin
Shameel Uddin

Posted on • Updated on

πŸš€ Mastering Asynchronous JavaScript: Choosing Between .then() and async/await

  1. Promise can be consumed from one of two ways:
  2. then (Introduced with promises)
  3. async/await (Introduced in later years)

We basically learned that consuming promises has better code readability after the introduction of async/await, whether it be an API call, database operation, reading a file from your filesystem or any async task.

Read more about it here:

Lets look at the example of consumption of promise with then and await:

const shameelPromise = new Promise((resolve) =>
  setTimeout(() => resolve("Promise 1 resolved"), 1000)
);
Enter fullscreen mode Exit fullscreen mode

Consuming promise with then:

shameelPromise.then((result) => {
  console.log("Using .then():", result);
}).catch((error) => {
  console.error("Using .then(): Promise rejected with error:", error);
});
Enter fullscreen mode Exit fullscreen mode

Consuming promise with async/await:

async function consumePromise() {
  try {
    const result = await shameelPromise;
    console.log("Using async/await:", result);
  } catch (error) {
    console.error("Using async/await: Promise rejected with error:", error);
  }
}

consumePromise();
Enter fullscreen mode Exit fullscreen mode

Choosing Between .then() and await

Choosing .then()

  • Use .then() when you want to execute actions asynchronously without blocking the rest of the code. This is suitable when you want to handle a Promise's resolution or rejection while allowing other parts of your program to continue running.
  • This does not pause the execution of the code.

Here's an example to illustrate this:

console.log("-- Shameel 1 --");
const request1 = fetch("https://jsonplaceholder.typicode.com/users/1").then(
  (response) => response.json()
);
const request2 = fetch("https://jsonplaceholder.typicode.com/users/2").then(
  (response) => response.json()
);

Promise.all([request1, request2])
  .then(([data1, data2]) => {
    // Both responses are available here
    console.log("Data from request 1:", data1?.id);
    console.log("Data from request 2:", data2?.id);
  })
  .catch((error) => {
    console.error("Error:", error);
  });
console.log("-- Shameel 2 --");
// Code here continues executing without waiting for the responses
Enter fullscreen mode Exit fullscreen mode

In this code, we are sending concurrent API requests, not serial ones. You can read about serial vs. parallel API calling here

After running above code, you will see a response like this:

-- Shameel 1 --
-- Shameel 2 --
Data from request 1: 1
Data from request 2: 2
Enter fullscreen mode Exit fullscreen mode

You can see that -- Shameel 1 -- and -- Shameel 2-- appeared immediately because the code was not paused.

PS. if you want to know about Promise.all(), please have a look at this:

Choosing await

  • Use await within an async function when you need to wait for a Promise to be resolved before proceeding with the rest of the code. This is helpful when you want to ensure that certain operations are completed before moving on.
  • This pauses the execution of the code.
async function fetchData() {
  try {
    const [response1, response2] = await Promise.all([
      fetch('https://api.example.com/data1'),
      fetch('https://api.example.com/data2')
    ]);

    const data1 = await response1.json();
    const data2 = await response2.json();

    // Both responses are available here
    console.log('Data from request 1:', data1);
    console.log('Data from request 2:', data2);
  } catch (error) {
    console.error('Error:', error);
  }
}

fetchData();

// Code here continues executing after fetchData() is called
Enter fullscreen mode Exit fullscreen mode

You will see a response like this:

-- Shameel 1 --
Data from request 1: 1
Data from request 2: 2
-- Shameel 2 --
Enter fullscreen mode Exit fullscreen mode

You can see that -- Shameel 2-- appeared after the requests were fetched successfully. This is because the code execution was paused.

Conclusion

In JavaScript, Promises offer a way to manage asynchronous operations in a more organized and understandable manner. The combination of .then() and await provides developers with powerful tools for handling asynchronous tasks. By understanding when to use each approach, you can write cleaner and more efficient code while maintaining better control over the flow of your program. So whether you're handling network requests, file I/O, or any other asynchronous task, having a solid grasp of these concepts will undoubtedly elevate your JavaScript programming skills.

I hope you learned something from this :-)

Follow me for more such content:
LinkedIn: https://www.linkedin.com/in/shameeluddin/
Github: https://github.com/Shameel123

Top comments (0)