One of the very beautiful features that Javascript offers is the choice of writing either asynchronous or synchronous code at will. The fact that Javascript doesn’t necessarily force you to stick with one of these is what sets the language apart from any other language out there.
Understanding the differences between synchronous and asynchronous operations is the key to understanding Async/Await in Javascript so, let’s dive right in!!!
Synchronous vs Asynchronous Programming.
Synchronous Programming.
Simply put, synchronous programming is a type of programming that follows a blocking architecture where your program runs in a perfect sequence, in a specific order.
Say you’re building an application that carries out the following operations:
- Make a request to an API to get the list of all products purchased in the last 10 days.
- Write the result of the API request to a file (for some reasons).
- Calculate the total amount of products purchased.
- Store the result of the calculation to the Appsmith store.
- Read the contents of an uploaded JSON file.
- Upload the contents of the JSON file in step 5 to a database.
With synchronous programming, the above code will execute step by step and, if one takes too long, the rest of the program will not execute until that particular operation is completed. Say task 1 of the above tasks takes about 120s to complete (for whatever reason), the rest of the code from task 2 to task 6 will have to wait for the whole 120s until the first task is completed.
While this carries some kind of advantage, it also has some disadvantages that can’t be overlooked, take for instance, if a particular task or process fails, all other processes automatically fail. This is where asynchronous programming comes to the rescue.
Asynchronous Programming.
Unlike synchronous programming, asynchronous programming takes a non-blocking approach to execution of tasks and operations. What this means is that one task or operation doesn’t necessarily block the execution of the following operations.
In the case of the operations we listed above, while we wait for the API to return the list of products purchased within the last 10 days, we can proceed to read the contents of the uploaded JSON file and the failure or success of one doesn’t necessarily affect the other (unless you want it to).
How is this even possible?!!!
This is possible with the use of something called a Promise.
You know when you were younger and you’d ask your dad for a new pair of shoes as a birthday gift? Well, if your dad was like mine and you were like me, his response would have been “I promise to give you this only if you get your grades up”. Now, you know the promise has the potential of being fulfilled or rejected at some point depending on how your grades turn out, and because you’were not like me, you’d probably get a new pair of shoes on your birthday.
Promises are not any different in Javascript. They represent the eventual completion (or failure) of an asynchronous operation and its resulting value. What this means is that, when you perform an asynchronous operation, the operation returns a promise back to you that you can use to track if the operation was successful or it failed for some reasons
Consuming a Promise in Javascript.
You might be wondering, how do I get my desired data out of a promise?
With any asynchronous call, Javascript offers something I would call a **then attatchment (**because that’s what I like to call it) which basically means that, when you have a function that returns a promise, javascript allows you to attach a .then() to the function like so: functionThatReturnsAPromise().then()
The .then() function accepts an argument which is the data returned by your function.
functionThatReturnsAPromise().then(data => {
console.log(data);
// or do whatever you want with your data;
})
Our final question is that when this function fails, how do I handle the error? Like the .then() method, Javascript also offers the .catch() method so you can use this to handle error cases like so:
functionThatReturnsAPromise().then(data => {
console.log(data);
// or do whatever you want with your data;
}).catch(err => {
console.log(err);
// or handle your error however you like
})
How about this…?
Despite the fact that Javascript gives us a way to write code that doesn’t block each other, sometimes, we still have some part of our code where the result of one operation is the input of another operation. Say, for instance, you have an API that returns the list of purchases in the last 10 days which you want to use to calculate the total amount for the purchase and then finally, display on a widget. In this case, you need the API result to be successful right now before moving on to your calculation.
The issue with this is that, your call to the API is asynchronous and your calculation is most likely synchronous. What you need here is a way to make asynchrounousAPI calls to act like it’s synchronous.
Async/Await to the rescue…
Javascript allows you to write “asynchronously synchronous code”. What this means is that you can make Javascript wait for the result of an asynchronous call and not move on to the next line of code until that call is completed. This is possible by using Async/Await.
You start by declaring a function with an async keyword like so:
async myFunction() {
// do something
}
The async keyword equips your function with the ability to perform synchronous-like asynchronous operations without the .then() method. How? You wait for it like so:
async myFunction() {
const result = await products_query();
}
The await keyword waits for your function to finish execution and stores the result of the function call to the result variable before moving to the next line. To handle any error that comes with this, you can just wrap the whole call in a try…catch block like so
async myFunction() {
try {
const result = await products_query();
}catch(err) {
console.log(err);
// or do whatever you like with your error.
}
}
On Appsmith, calling a query, running a JsObject, storing a value in, or fetching a value from the Appsmith store are all asynchronous function calls so, remember to await their results when you need them to happen before moving on to the next thing!
Happy Hacking!!!