Fetch, and the Promise of Asynchronicity
Where I started
I always had friends who were interested in coding in some form or another. Whether it was learning HTML (mostly in a piecemeal fashion) in order to customize a MySpace page, or delving into instructional books to try and really learn a language. It seemed that there was always someone around me who was doing something involving code on some level. For me though, there wasn't a whole lot of interest in what made some of my favorite things work. Like most growing up in the late 90's and early 2000's I was obsessed with video games. I had some fantasies of making my own one day, but they were fleeting at best.
Fast forward a couple of decades and I found myself starting my journey behind the curtain, seeking to learn how some of the most influential technology that I, and most other people, interact with on a daily basis works. I started with an introductory book on Python, and while I wasn't quite as smitten as I had been with games when I was a kid, I liked what I found. The puzzle-solving nature of the work intrigued me, and learning about writing algorithms to process and manipulate data scratched an itch I didn't know I had. However, as I worked my way through that book I felt something was missing. I was learning this language, solving the problems provided, and writing algorithms, all in isolation. Fast forward yet again, this time just a few months, and I finally came across the very method for filling that gap I had felt prior: Enter fetch()
.
fetch()
, and what it's for
//An example of the initial fetch call
fetch('http://exampleapi.com/example')
MDN Web Docs describes the Fetch API as providing "an interface for fetching resources (including across the network)." Very basically, the fetch()
method is used in code to utilize the aforementioned interface and interact with those resources. Using different methods in our fetch()
requests such as "POST", "PATCH", and "DELETE", enables us to add data to, modify, and delete a resource respectively. It's more than worth noting that the fetch()
request does not require an explicit method when called to get (or fetch) a resource, it does that by default.
fetch()
is asynchronous, but why?
//Here's some synchronous code
console.log('This will print first!')
console.log('This will print second!')
console.log('This will print third!')
Normally Javascript runs synchronously, meaning each line of code is executed in order. If a process takes a long time to execute, too bad, the program doesn't get to move on. However, fetch()
behaves asynchronously, which means that it's removed from the normal flow of our program. This enables us to build more responsive programs, allowing the continued execution of our code while certain processes are resolved. As an example, let's look at synchronicity through the lens of building a house. Following the rules of synchronous code, we'd have to wait for each piece of the house to be built from the ground up in order to move on to the next step. First, the foundation has to be laid, then the walls built, then the roof. This means that if there's some holdup with the construction of the walls, our roof can't be built until it's settled. However, with asynchronicity, we could build all of our components separately and put them together at the end, not having to wait for our walls to be built to get started on our roof. Going back to our example, what if the companies doing the foundation work, building the walls, and building the roof are all separate? There would have to be some sort of communication or plan about what everyone was doing.
//Here's fetch doing its asynchronous thing!
fetch('http://exampleapi.com/example')
.then(response => response.json())
.then(data => console.log(data))
console.log('This will print before the data!')
The promise
fetch('http://exampleapi.com/example')
//The fetch() call creates a promise, which gets passed to .then()
.then(response => response.json())
//.then() creates its own promise, which it passes on
.then(data => exampleFunction(data))
//Finally, the second .then() recieves the final promise
Continuing with our house, each company should let each other (or better yet, a project manager) what the outcome of their task is. If the walls never get finished because of supply chain issues, now we're dealing with a giant gazebo instead of a house. The same holds true for our code. When we use fetch()
it returns something called a "promise". The promise is a placeholder for whatever the result of the fetch request is, whether it succeeds or fails, telling subsequent asynchronous lines of code dependent on the outcome that there will be some value to work with when the process is finished. After making our fetch()
request, we can use .then()
to handle whatever response we get. Typically, this consists of what is referred to as a "promise chain", since each .then()
returns a promise of its own to the next .then()
, enabling us to do things like convert the data we get back from JSON (JavaScript Object Notation, a format commonly used to send data to and from servers) to JavaScript objects that we can then use and manipulate in our program.
Where I am now
Learning about fetch()
opened the door to a universe of possibility. After having spent the opening stages of my journey learning how to manipulate data in isolation, gaining the ability to access untold amounts of data feels like the world is at my fingertips. The possibilities that access opens up, combined with the increased efficiency and practicality that asynchronous code provides, have me very excited for what lies ahead.