DEV Community

Noah Hughes
Noah Hughes

Posted on

Async Await vs Fetch.Then()

In my time preparing for my bootcamp, I decided to get some practice with some web development fundamentals. One of those being working with APIs and manipulating JSONs that were returned to me. In my journey to self-teach myself how to do fetch calls, I came across a method that used async functions and a keyword of await.

const apiCall = async () => {
   const apiCallPromise  = await 
   fetch('https://api.example.com/data');
   const apiCallObj = await apiCallPromise.json();
   return apiCallObj;
};
Enter fullscreen mode Exit fullscreen mode

This snippet is a quick and easy function to make a simple fetch request and return the parsed JSON as a mutable object. What the code is doing in practice is making my GET request to the endpoint, telling the code to wait for a resolved promise, taking that promise and turning it into an object using the .json() function, and finally returning that object. This is simple, clean, and predictable code. You always know what object you will get back is, and if you pass in parameters, you can easily control which endpoint you hit on the API with string interpolation.

When I began my bootcamp and started working my way through the course, I inevitably reached the chapter focused on JSONs and fetch, post, patch, delete etc. While going through this chapter I noticed we were taught another way of doing fetch requests. They weren't handle in async functions, they didn't use the await keyword, and they were linking callback functions to the initial fetch.

const apiCall = () => {
   fetch('https://api.example.com/data')
   .then((resp) => resp.json)
   .then((data) => {
      return data;
   });
}
Enter fullscreen mode Exit fullscreen mode

Now that snippet looks much different from what I had learned. What is it doing exactly though? When invoked, the function will send my GET request to the target endpoint, it will then (get it?) invoke the then() function which takes a callback function. In this example that call-back function is simply returning the object of the response after invoking .json() on it. After doing so then() will take that parsed object and do something with it. That can be invoking another call back, changing the content of the object then, or simply returning it as my example does.

So, what is the difference between these two methods for handling requests? Is one better than the other?

There is three key differences between async await and then(). They boil down to syntax, error handling, and general code organization.

The syntax differences between the two are shown above; however, there is more going on behind the scenes of the syntax. With await, we are able to write asynchronous code in a way that looks and feels synchronous. await is allowing us to pause code execution until our promise is resolved and then again while parsing the JSON we get back from that fulfillment. With then() we are promise chaining. We are saying after this, do this, and so on and so on. This is what is allowing us to asynchronously handle the request sent to the endpoint. This promise chaining is more explicit and allows us to handle that promise in multiple ways before returning it.

The next difference is how these two methods handle errors. With await we are able to create a try and catch code block.

const apiCall = async () => {
   try{
      const apiCallPromise  = await 
      fetch('https://api.example.com/data');
   };
   const apiCallObj = await apiCallPromise.json();
   return apiCallObj;
   catch(error){
      console.error(error);
   };
};
Enter fullscreen mode Exit fullscreen mode

This code block is acting as an if-else but one designed for acting with requests. What this is doing is in the try if the requests is successful, continue on and return the object; otherwise, throw this error to the console and tell me the error with the requests. With catch(), your errors are handled in your promise chain just as your then()s are.

const apiCall = () => {
   fetch('https://api.example.com/data')
   .then((resp) => resp.json)
   .then((data) => {
      return data;
   });
   .catch((error) => console.error('Error:', error));
};
Enter fullscreen mode Exit fullscreen mode

This snippet functions exactly the same as done with the await example but the difference is that here, catch() is expecting a callback function.

The third key difference between the await and then() comes down to code organization. I have touched on it already but using await allows you to write your code in a more linear and organized manner. You can perform subsequent operations on the fetched response immediately after the await statement, which can make the code flow more naturally. With then(), you need to chain multiple then() calls to handle the response and subsequent processing. This can sometimes lead to nested or cascading then() calls, which may make the code harder to read and maintain.

So, which is better? I don't believe there is a definitive answer to this question. While I do have my preference in using await, I believe it comes down to the context of your application, use case, and preference.

Top comments (3)

Collapse
 
tracygjg profile image
Tracy Gilmore • Edited

Hi Noah,
Please correct me if I am wrong but should const apiCall = await () not be const apiCall = async () in the examples above?

You might want to use syntax highlighting by including 'javascript' immediately after the initial tripple backticks of your code examples. See this guide.
Regards, Tracy

Collapse
 
paperbyte profile image
Noah Hughes

You are completely correct! I missed that in my quick review before publishing. It has been updated, thank you for catching that!

Collapse
 
pjotrb profile image
Peter Broekhuizen • Edited

The try ... catch example is wrong, it has code between the try { } block and the catch part.

Also there can never be a ; after the try { } block because it needs the catch part to follow immediately. In fact no { } block ever needs to be followed by a ;.