Asynchronous Promises with JavaScript
JavaScript generally executes in a synchronous fashion. Meaning the code runs from top to bottom, one line or block at a time, and functions rely on completion of other functions to finish executing before the the program can run them. For example:

Task A runs in the program, but Task B cannot start execution before Task A is finished. Same circumstances occur with Task C. Task B must be completed before Task C can be executed.
This is the basis of synchronous program execution. JavaScript also is a single threaded language. Meaning that each thread is a single process used to complete certain tasks. Each thread can only perform a single task at a time.
With today’s computers, which have multiple core processors some languages can perform tasks with multiple threads using different processors. JavaScript can use Web Workers, which allow for separate tasks to be completed in the background separate from the main thread. The problem with Worker threads is that they cannot access the DOM (Document Object Model). This means that Web Workers cannot do anything to manipulate the UI.
In order to solve this issue, browsers allow developers to use asynchronous operations. We can run these asynchronous operations using something called promises.
Asynchronous Promises
With asynchronous promises, it’s important to understand what asynchronous operations actually mean. Asynchronous operations basically mean that programs can run operations in the background, and continue to execute the rest of the program in the meantime. Here’s a quick visual example:

You can think of it as the browser saying something like, “I promise to return a result as soon I finish completing the task.” Promises can only have two outcomes, successful completion or failure.
In this case let’s take a look at using fetch()
as our asynchronous operation:
In this example (starring my newly adopted puppy Gunnar :)), we use fetch to access the image file. After fetching, we use .then()
with a callback function to do a couple things:
- create an
img
element and set thesrc
attribute to the response’s url key. Since the.then()
block has access to the promise object we can access the values within that object using dot notation and the correlating keys. Usingconsole.log(res)
allows us to examine the promise object. - Then we set the class name again using dot notation. This way we can style the size of the image in the
styles.css
files imported at the top of this file. - Finally we can append the newly created
img
element to thediv
element that we set to thecontainer
variable previous to fetching.
In this case, the fetch returned a successful promise completion. Sometimes however, fetch will return a promise with errors because it failed. In these circumstances, we can use .catch()
blocks to catch the error.
We can then do what we want with the error responses. Here is an example of error handling:

In the above example, .catch((error) => {console.log('There has been a problem with your fetch operation: ' + error.message)}
is where we are handling errors. We console log a string and error.message
to display the exact error that results from the failed fetch.
Conclusion
In conclusion, async operations within our code allow us to perform operations that run in the background. While the rest of our program is able to be executed. Using promises, we can run operations in the background using the promise object that is returned from .fetch()
blocks. This allows developers to have more flexible and user friendly code.