Aug 17, 2019

Learn to handle asynchronous functions in JavaScript


One of the things that make JavaScript an impressive language is the ability to perform asynchronous tasks. Asynchronous? Yes, JavaScript despite being a language that processes in a single thread can continue its execution regardless of whether the previous function has not completed.

Not too fast, This capability is only possible with some functions. Let's look at a small example.

    function sum (x, y) {
    console.log (x + y)
    }
    
    setTimeout (function () {
    sum (2,2)
    }, 1000)
    
    sum (4.4)

Which of the two sums will be shown first? What is setTimeout? Why do I keep asking myself these questions? xd

Ok, if you already despaired and tried on your browser console, you will have noticed that the 8 was shown first that 4. This is because setTimeout is an asynchronous function that receives a function as the first parameter and the amount of milli seconds that function will be executed.

But what if we change it to 0 the second setTimeout parameter?

function sum (x, y) {
console.log (x + y)
}

setTimeout (function () {
sum (2,2)
}, 0)

sum (4.4)

Voila! We get the same result. How is this possible?

The magic of Event Loop

To understand how this whole concept works, we must take into account that JavaScript natively does not have things like setTimeout, but are APIs supplied by its execution environment such as * Browser * or others such as * Node.js *.

The Event Loop, explained in a simplistic way, is the one in charge of handling the events that will be executed, according to their nature.

Describing what happens in the image:

We see that the JavaScript environment is composed of:

  • The Memory Heap: which is the use of memory that uses language for its objects.
  • The Call Stack:: which is the stack where the context is accepted the code that is executed.

Apart from this, we have the web API (* which can also be called the runtime API *). Also the Callback Queue or Queue which are the functions that will be processed.

Finally, the Event Loop is responsible for moving the functions of the Queue to Call Stack.

Let's see an example:

console.log ("hello")

setTimeout (timeout () function {
console.log ("world")
}, 5000)

console.log ("Ubykuo everywhere, everywhere")

loop

We see that the timeout () function is processed by the Web API. After being completed, go to Queue so that the end is executed after you have already shown the last console.log.

Well... how do we handle it?

What happens if we need to wait or execute after an asynchronous function is completed?

There are 2 ways to handle these types of situations. Although this section deserves its own post, we will show some of the ways in which these types of situations are handled.

Callbacks

Callbacks are functions that are passed as a parameter to be executed after certain operations.

function greet (name) {
console.log ("Hello" + name)
}

function receive Invited Juan (callback) {
guest var = "Juan"
callback (guest)
}

receive Invited Juan (greet) // Hi Juan

Its use in asynchronous functions would be as follows:

function greet (name) {
console.log ("Hello" + name)
}

function receive JuanMasTarde (callback) {
setTimeout (function () {
guest var = "Juan"
callback (guest)
}, 5000)
}

Receive JuanMasTarde (greet)
// ... (Wait for 5 seconds)
// Hello John

Although this form at first glance seems simple, it can be affected when many functions need to be nested, this problem is called Callbacks Hell

Promises

Promise or (Promise) is an object in JavaScript that represents a value that may or may not be available in the future. They were implemented to solve (in a better structured way) the asynchronous tasks that were performed with the Callbacks.

The promises are created with the keyword 'new' and passing a callback that receives two parameters that are also functions, which will be called if the operation was successful (resolve) and if something failed (*reject *).

Let's see an example:

function addMasTardeShow (x, y) {
var newPromesa = new Promise (function (resolve, reject) {
if (! x ||! y) {
reject ("Missing number")
}

setTimeout (function () {
solve (x + y)
}, 1000)
})
return newPromise
}

addRead MoreShow (5.3)
.then (function (result) {
console.log (result)
})
.catch (function (error) {
console.error (error)
})

After we have this asynchronous function, we use then when we get the result and catch to capture the errors.

The advantages of promises is that already many of the new asynchronous functionalities that are offered to the language, return a default promise. This is the case of fetch, which is provided by browsers to make HTTP requests.

const url = "https://example.com/api/users"
const body = {
// ...
}

fetch (url, body)
.then (function (response) {
return response.json ()
})
.then (function (jsonResponse) {
return console.log (jsonResponse)
})
.catch (function (error) {
console.error (error)
})

Here we see that in addition to fetch also Body.json uses promise. The latter is the object resulting from the request, which in turn uses this method to convert the JSON object response.

Async - Await

Finally, we have this method, introduced as standard in the ECMA 2017 specification. Like then and catch they work with Promise, only in a very particular way and making the syntax more readable.

function async getUsers () {
const url = "https://example.com/api/users"
const body = {
// ...
}

const response = await fetch (url, body)
const jsonResponse = await response.json ()
}

The first thing to do is create a function with the keyword asycn in front. So we can use the await within this function. The await must be used before the sentence that will return the promise. So instead of getting the Promise object, we will get the expected value.

Conclusion

We must take into account that JavaScript has functions that will not return their value immediately and learn to use this behavior in our favor. Managing this knowledge gives us many alternatives and the possibility of using all language capabilities.

What do you think?

Learn to handle asynchronous functions in JavaScript
Commentarios