Asynchronous Programming: Using Fetch and Then

Sasha Brockman - Dec 20 '23 - - Dev Community

When building a webpage, we almost always want to access information found in other places on the internet. Not only does it create a more interesting and engaging application, it also prevents us from having to have all of the information needed for our site on a single server. In order to access data remotely with JavaScript, we use the fetch() function.

Fetch

The fetch() function is a global method implemented by Window and WorkerGlobalScope. Because of this, fetch() is available to use in virtually every context in which you might need it. It takes time to access information online, however. Generally speaking, we usually don't want our code to have to wait for a single fetch request to finish before moving on to other steps. Luckily for us, fetch() is an asynchronous function, meaning it returns a Promise instance while the next lines of code can run.

Promises

A Promise instance is exactly what it sounds like; it's a promise that the data will be passed to the code as soon as the information from the fetch() request is received.

That leaves us with another problem, however. If the rest of the code runs while the Promise is waiting to resolve, then the information received by fetch() will be left with no code to handle it. To solve this issue, there are a couple of tools we can use: await and then().

Await and Then

Await is an operator that is useful when attempting to assign a Promise instance to a variable, while then() is used to immediately call a callback function when the Promise resolves. For this blog, we're going to be looking at how fetch() and then() interact with each other and leave await for another time.

Using Fetch

Building on what we read earlier, the fetch() function can take a couple arguments but only needs one. For simplicity's sake, we will only be looking at the required argument, but keep in mind there are other options that can be added to manipulate the functionality.

The first and main argument passed to the fetch() function is the resource, or the URL of the information that you are trying to access.

fetch('http://localhost:3000/data')
Enter fullscreen mode Exit fullscreen mode

As stated earlier, fetch() will attempt to access the data, and while doing so, will return a Promise instance that will be replaced with the real information at a later time. We call this resolved request the Response object.

Using Then

Once we have a Promise instance, it can then be passed to the then() function to be used. then() is a method used by Promise instances that has one mandatory argument and an optional one: a callback function to be used on successful resolutions and/or one for rejected resolutions of the Promise. We will start by only looking at instances of then() using only one argument.

Combined with a fetch request, it looks something like this:

fetch('http://localhost:3000/data')
.then(res => res.json())
Enter fullscreen mode Exit fullscreen mode

In the example above, we took the response from the fetch() request and passed it to an arrow function. This callback function changes the JSON string that is the response and returns a usable object for later use. Remember that this response is only translated once the Promise passed to the then() function resolves.

From here, we can link together at many then() functions as we desire. This is because each then() function immediately returns a Promise instance.

fetch(`http://localhost:3000/data`)
.then(res => res.json())
.then(response => someFunction(response))
.then(someValue => console.log(someValue))
Enter fullscreen mode Exit fullscreen mode

As each Promise is fulfilled, the callback functions will be called in the order that they are chained.

As mentioned earlier, we can add another call back function as an argument to a then() function to be used in case our original Promise does not resolve. In that case, we would have something like this:

fetch(`http://localhost:3000/data`)
.then(res => res.json(), () => console.log("fetch unsuccessful"))
Enter fullscreen mode Exit fullscreen mode

Resolving Promises

A then() function will choose either of the callback functions depending on how the Promise passed to it resolves. These are the ways Promises can be handled:

•If a value is returned, the Promise is fulfilled with the returned value as the value of the Promise.
•If no value is returned, the Promise is fulfilled with undefined as the value.
•If an error is thrown, the Promise is rejected with the error being its value.
•If a fulfilled Promise is returned, the Promise is fulfilled with the returned value as its own value.
•If a rejected Promise is returned, the Promise is rejected and shares the returned value.
•If another pending Promise is returned, the Promise remains pending and becomes fulfilled as soon as the previous Promise resolves.

There are various different ways to alter the behavior of the fetch() and then() methods beyond what has been discussed in this blog. For example, we can add more arguments to fetch() such as a method, headers, body, etc. However, for simplistic use, this blog covers most of what you need to know. Thank you for reading!

. . . .
Terabox Video Player