ASYNCHRONOUS JAVASCRIPT

ASYNCHRONOUS JAVASCRIPT

Asynchronous JavaScript is a fairly advanced topic, and you are advised to work through JavaScript first steps and basics if you are a beginner.

One of the keys to writing a successful web application is being able to make dozens of AJAX calls per page.Let us first talk about Asynchronicity itself.

Asynchronicity

In a synchronous programming model, things happen one at a time. When you call a function that performs a long-running action, it returns only when the action has finished and it can return the result. This stops your program for the time the action takes.

An asynchronous model allows multiple things to happen at the same time. When you start an action, your program continues to run. When the action finishes, the program is informed and gets access to the result (for example, the data read from disk).

We can compare synchronous and asynchronous programming using a small example: a program that fetches two resources from the network and then combines results.

In a synchronous environment, where the request function returns only after it has done its work, the easiest way to perform this task is to make the requests one after the other. This has the drawback that the second request will be started only when the first has finished. The total time taken will be at least the sum of the two response times.

## SOLUTIONS

The first and the most straightforward solution came in the form of nested functions as callbacks. This solution led to something called callback hell, and too many applications still feel the burn of it.

Then, we got Promises. This pattern made the code a lot easier to read, but it was a far cry from the Don’t Repeat Yourself (DRY) principle. There were still too many cases where you had to repeat the same pieces of code to properly manage the application’s flow. The latest addition, in the form of async/await statements, finally made asynchronous code in JavaScript as easy to read and write as any other piece of code.

Let’s take a look at the examples of each of these solutions and reflect on the evolution of asynchronous programming in JavaScript.

## Callbacks

Callbacks are simple functions which are used to notify the calling instance when an asynchronous code block has been executed and the result is available. Using callbacks is simple as we only need to deal with functions, take a look at the following example:

const getTodo = callback => {
    setTimeout(() => {
       callback ({ text: 'Complete Code Example' })
    }, 2000)
}
getTodo(todo => {
    console.log(todo.text)
})

The getTodo function is defined, so that it takes the callback function as a parameter. Inside getTodo we’re again using the getTimeout function to delay the execution of code for 2000 milliseconds. Instead of just returning the object we’re now calling the callback function. As an argument we’re passing in the object which should be returned. When calling getTodo we now need to make sure to pass in a callback function as a parameter. In the example from above we’re doing this by using the fat arrow syntax to define an anonymous function. Inside that functions we’re outputting todo.text. This function is invoked from inside of getTodo when the 2000 millisecond delay is passed.

## Promises

Now that you’ve learnt about callbacks lets turn to Promises which is a built-in language feature of JavaScript and makes handling asynchronous code easier and more readable:

const getTodo = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            let error = false;
            if(!error)
                resolve({ text: 'Complete Code Example' })
            else
                reject()
        }, 2000)     
    })
}
getTodo().then(todo => {
    console.log(todo.text)
})

This code is basically doing the same as seen before in our callback example but with Promises. Inside the getTodo function we’re making sure to return a new Promise. The constructor of the Promise class is expecting to get a function which is containing the asynchronous code as a parameter. This function is then expecting to get two parameter, resolve and reject, and containing the asynchronous code which needs to be executed. In case the asynchronous code has been executed successfully we’re calling resolve. In case of errors we’re calling the reject function.

When calling the getTodo function we’re now able to chain a call of then. Then is expecting to get handed over a function which is executed once the Promise is being resolved. As a parameter this function gets what is passed into the call of resolve. In the example from above we’re using the function body to print the content of text property to the console once again.

## Async / Await

Now that you have learnt about Promises and how Promises may help you to deal with asynchronous JavaScript code we can go one step further and learn about two new language keywords which have been added to JavaScript with the ES2017 language specification. By using async and await the handling of promises is becoming more easier, let’s take a look at the following code:

const getTodo = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            let error = false;
            if(!error)
                resolve({ text: 'Complete Code Example' })
            else
                reject()
        }, 2000)     
    })
}
async function fetchTodo () {
    const todo = await getTodo()
    return todo
}
fetchTodo().then(todo => console.log(todo.text))

The implementation of the getTodo function has not changed at all. Still the Promise is created and depending on the value of the error variable it is resolved or rejected like seen before. What has changed is the way the getTodo function is called. A new function fetchTodo is being implemented and the async keyword is used to indicate that this function is executing asynchronous code based on a Promise. Inside of fetchTodo we’re calling the getTodo method by using the keyword await. This indicates that getTodo is returning a Promise and we have to wait for the Promise to be resolved (or rejected). The result of what is being returned from the promise is stored in todo. In the next line of code the todo object is being returned. This is possible because by using the keyword await we’re making sure that the next line of code is being executed after the Promise (returned from getTodo) has been resolved.

That’s it for now… Thank you.

References: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Introducing