If you've never been exposed to asynchronous programming before, javascript has functions that are interesting and also annoying if you don't know whats happening. Towards the end of the article, we'll talk about how to turn a javascript asynchronous function, into a synchronous one and how it can benefit us.
The easiest way to think of asynchronous and synchronous programming in a non-programming way is a person who is multi-tasking.
Pretend you are a a barista who is working a morning shift at a coffee shop. This morning you have three tasks you need to complete before you open up the store.
My tasks for this morning:
- Brew coffee
- Clean the counter
- Play coffee shop music
Now lets see how an asynchronous barista would act compared to a synchronous barista.
Asynchronous Barista | Synchronous Barista |
---|---|
|
|
As we can see in the comparison, the asynchronous barista was able to do other tasks while waiting for the coffee to finish brewing. On the other hand, the synchronous barista, waited for the coffee to completely finish brewing before moving on to do other tasks.
Now lets translate this back into our Javascript. Although Javascript is a single-threaded language (meaning it can only do one thing a time), it is not fully asynchronous. But Javascript does have functions that are asynchronous.
An asynchronous function means exactly the same in the barista scenario. When the asynchronous function is called, feel free to do other things until the asynchronous function is done.
Example:
One asynchronous function in particular is the fetch()
function that returns a promise. The fetch()
function can access an api and fetch information from it and returns that information as a Promise
. As you can imagine, depending on the information you try to fetch, it might take a while. Since fetch()
, is an asynchronous function, the IDE will fetch this information in the background while doing other tasks, and will get back to the Promise when its done fetching it.
This is different to a synchronous fetch in which nothing else will get done until the information is fully fetched.
Now you must be thinking, wow Synchronicity sucks! Asynchronous for the win!!
BUT... asynchronicity and synchronicity have their own pros and cons.
Yes Async sounds super efficient but there are some drawbacks to it that is easily solved by turning this Asynchronous fetch call into a synchronous fetch call.
Now imagine you need to get a list of items and then display those items onto the DOM. We'd do something like this.
Warning: This will not work.
function getItems(){
let list = [];
fetch('http://localhost:3000/items')
.then(resp=>resp.json())
.then(items=>{
for(item of items){
new Item(item);
list.push(item);
});
return list
}
// a function to get a list of items^^
// now lets display those items
function displayItems(){
let items = getItems();
for(item of items){
//create element;
//element.innerHTML(item);
//document.body.append(element);
}
}
If you've never worked with asynchronous functions before, it might be hard to see the problem here (I spent hours not understanding what was going on). But running displayItems()
will actually do nothing.
Wait, but it's getting items from the fetch and assigning the return to a variable.
Yes but no. We were expecting 'items' to be a list of items returned by the getItems()
function. Although the main issue is that getItems()
is making a fetch call which is an asynchronous function.
This means that by the time the function tries to iterate over the list of items to then try and display each item, the fetch call still has not finished fetching the information which means that the list is empty, therefore we are iterating over nothing.
If you want to give it a shot, run this function and put a debugger
after the getItems()
call and right before the for loop. Check the variable items, and you will see that it is in fact empty.
So how do we get around this.
Well in this scenario, the asynchronous function is actually not working in our favor and so therefore we would want to make the function synchronous.
The asynchronous function was not working in our favor because we want to do things in according to that list that is returned by the fetch call. Meaning that we shouldn't be doing anything else until the fetch is finished.
So to make our asynchronous fetch call into a synchronous fetch call.
There are two keywords that we'll need to understand in order to do this. async
and await
. Using async
in front of a function declaration will turn the function into an asynchronous function. While using await
in front of something will wait until that specific thing is finished before moving on.
We'll use these keywords as follows.
async function displayItems(){
let items = await getItems();
for(item of items){
//create element;
//element.innerHTML(item);
//document.body.append(element);
}
}
The keyword async
is placed before declaring the function and the keyword await
is placed right before the thing you want to wait on.
In our case, this function is now asynchronous but the fetch call is sort of synchronous in this case with the fact that were waiting for the fetch call to be completed before moving on.
Congrats! You finished reading! Hopefully you understand asynchronous and synchronous programming a little better now!
Side note... .then()
works like await
in the sense that .then() waits for the fetch to return the promise before acting on that promise
Top comments (0)