DEV Community

Harshit Pandit
Harshit Pandit

Posted on

What the heck does asynchronous mean ??

Have you ever visited the Spotify Web App?? How does it even loads an artist data and play the music at the same time? Even while the music is playing, you can visit a different tab and still work properly!!

Of course the app was programmed in the way so that it handles multiple tasks at a time. But in we've heard in programming, everything is executed sequentially, line-by-line, so what the hell is going on ??

This is where the concept of asynchronous programming comes in.

What's wrong with synchronous programming?

Synchronous programming basically means executing your code line by line. What comes first is executed first, no matter how long it takes.

Here's a simple example in JavaScript

console.log('This is the first line');

const data = readFile('someFile.txt')
console.log(data)

const response = requestAnApi('some url')
if(response.status==404){
    console.log('You got a 404 response');
} else{
    console.log('You got a valid response')
}
Enter fullscreen mode Exit fullscreen mode

It's pretty straightforward, and it obviously makes sense that we want some certain tasks to be performed earlier than others.

But this isn't something we would want at all times.
What would you do if you're requesting some data from an API that takes more than 10 seconds, only to get a 404 response?? The rest of the code would literally stop working.

I've created a pen where we will try to see what's wrong with synchronous programming through a slow HTTP request

While you requested the data, the page became unresponsive. That shouldn't be the case because requesting some data and editing a text is totally different!!

So what is the workaround for this??

Asynchronous programming

Yes this is what this blog is about. What is asynchronous programming and how is it useful?

It is basically a way to enable our code to respond to all the events and still run a long, time-taking task on the background. The moment this long running task is finished, we are presented with that result.

And yes it comes very handy in use cases like in the pen above, where we want to get some response but also edit the text at the same time.

Easy-peasy, but HOW do we do it practically ?

Many languages have a keyword called async that enables us to write asynchronous code. It's also available in JavaScript but before we get to that, we need to know what are Promises.

Will smith confused

Unlike the case of politicians, JavaScript promises are actually executed and they always return something. Whether it is an error or some helpful response, they never stop until the task is fully executed.

Syntax and examples

In JavaScript, promises are defined just like an instance of a class object along with a function inside that always give a response.

The response is either 'resolved' or 'rejected' depending upon the execution of the function.

const adultPromise = new Promise((resolve,reject) => {
    // let's say this takes long time to execute
    let age = 18;
    let isAdult = age>18 ? true : false;
    if(isAdult){
        resolve('You can vote')
    }
    reject('You cannot vote')
})
Enter fullscreen mode Exit fullscreen mode

This is a simple promise that checks whether the age is more than 18 or not. To execute and get result of this promise, we get the methods then,catch and finally

This is just like try,catch and finally for error handling.
The way this promise is executed is -

adultPromise
    .then(value => {
        console.log(value); 
    })
    .catch(err => {
        console.error(err)
    })
    .finally(() => {
        console.log('Decision has been taken')
    })
Enter fullscreen mode Exit fullscreen mode

If the promise is resolved, the then method would be executed and if the promise is rejected, catch is executed like an error.

No matter whether the promise is resolved or rejected, the finally method is executed at any case.

We don't need any return statement here because on calling any of the two functions will finish the execution automatically, returning the data what's inside.

And yes, we can return anything from the promise, and I mean literally anything that are available - functions, objects, numbers,3 anything !!

But what if I want to pass my own arguments in the promise??

That would simply mean we wrap a function around the promise, get the arguments, maybe do some logic and return the promise. To demonstrate above example only -

const checkAdult = (age) => {
    return new Promise((resolve,reject) => {
        if(age>18){
            resolve('You can vote!');
        }
        reject('You cannot vote!');
    })
}

checkAdult(21)
    .then(value => console.log(value))
    .catch(err => console.error(err))
/* This prints out You can vote!  */

checkAdult(15)
    .then(value => console.log(value))
    .catch(err => console.error(err))

/* This prints out You cannot vote! as an error */
Enter fullscreen mode Exit fullscreen mode

Yes we can use the promise again and again just like any other variables if defined properly.

Promises and method chaining

We can perform method chaining in Promises just like any class instances. Note that this is only possible for then method.

checkAdult(21)
    .then(value => {
        console.log(value);
        return 21-value;
    })
    .then(diff => {
        console.log(`It's been ${diff} years since you turned 18`)
    })
Enter fullscreen mode Exit fullscreen mode

If a then block returns some value, we can get that value by chaining another then block. Here the diff variable contains the difference of the ages as returned by it's predecessor.

Is it wrong to have multiple then blocks for the same promise?

It's not uncommon to see multiple then statements chained together. But still, having tens of then blocks or a then block inside another then block can be very messy.

/* This code can run perfectly giving the output that we want, it's very messy to read
This is what is called as 'Promise hell'.
*/
datFetch()
    .then(response => {
        dataBase('User')
            .then(user => {
                response.verify()
                    .then(check => {
                        ...
                    })
            })

    })
Enter fullscreen mode Exit fullscreen mode

What is async in JavaScript?

The async and await keywords in JavaScript are just a 'syntactic sugar' around promises. In other words, it makes the promises more readable.

Apart from the top-level await feature introduced in ES2020, they are only possible to use in functions or class methods.

Let's use our above example in an async function.

async function main(){
    try{
        const decision = await checkAdult(21);
        console.log(decision)
    } catch(err){
        console.error(err)
    } finally{
        console.log('Decision is taken');
    }
}

main()
Enter fullscreen mode Exit fullscreen mode

This is even more readable than those then,catch blocks. I've wrapped the execution inside the try-catch blocks. It's more of a convention to follow this way.

The way this code executes is as follows :

1) The main function is declared as an asynchronous function. All of the code is executed in try-catch statements.
2) In the try block, the promise is called through the await statement and the result is given to decision variable.
3) The decision is logged into the console. If the promise throws any error, the control automatically shifts to catch block.
4) At the end, finally block is executed, logging that the decision is taken and the function is finished.

How exactly does await work?

While the promise is called like a function using await keyword, it's value is returned to a variable (in this case decision).
This does not stop the code from executing, instead, the code next line to it is executed and so on.

The promise is also executed in the background and the moment its value is available, it's returned to the assigned variable and all the code related to it is executed.

If all the further code is dependent on this variable, then and only then, the flow is 'put on hold' until the promise is executed.

This was all about asynchronous programming in a basic sense. More complicated stuff (like fetching an API and handling user input) can be executed using the same logic. Hopefully, this gave a better idea about how this works in JavaScript.

Until next time folks !! ✨

Top comments (0)