Async Function in JavaScript

Learn via video courses

Overview

Whenever we work on Javascript, we have to deal with tasks dependent on other tasks. Let us say we want to download a picture, edit it, and save it. The very first thing we need to do is to download the picture. Only after that can we edit and then save it. Hence we can see that every task is dependent on the previous one.

To achieve this functionality, we will end up with many nested callbacks known as callback hell. Luckily JS involved from callbacks to promises(ES2015) and then further to a more straightforward format of async/await (ES2017).

Syntax of Javascript Async Function

An async function in javascript is a combination of a generator and promises.

Async functions are built on top of traditional javascript promises. Thus they are just a higher level of generalization or an abstraction layer over-promise.

The purpose of async / await is to simplify the code syntax necessary to consume the promise returned by an API.

The async function in javascript is always prefixed with the async keyword and followed by the syntax of a simple javascript function. It operates asynchronously via the event loop and always makes a function returns a promise.

Syntax:

Example:

Parameters of Javascript Async Function

Lets us consider the following async function in javascript:

Here the parameters are:

  • name Optional:
    The name of the async function. (fun1)
  • param Optional:
    They are the name of the arguments that are passed to the async function. (param0)
  • statements Optional:
    This is the body of the async function in javascript. It can consist of a promise.

Return Value of Javascript Async Function

The Async function in javascript always returns a promise. Even if the async function in javascript is not explicitly returning a promise, the async function will internally return a promise.

This promise will be either resolved with the value returned by the function or rejected with a thrown exception from within the async function, which will depend on the conditions.

Output:

Note:
The main purpose of async/ await functions is to simplify the syntax of promises when they (promise) are used synchronously. It is similar to the combination of promise and generator.

Example of Async Function in Javascript

Understanding an async function in javascript with the help of a real-world example is helpful:

Let us suppose we wish to have some tomato juice made at home, but there are a few steps to be followed:

  1. We need to buy some tomatoes from the market.
  2. We need to peel the tomatoes.
  3. We need to add it to a juicer to make the juice.

Code using async await:

Output:

Benefits of using an async function in javascript:

  • In the case of API calls, fetching data from the database or any information from the server.
  • In the case of using the timeouts functionality.
  • Increasing the responsiveness and performance of the application in case of extended running programs.
  • Organizing the code to look clean and readable.

What is Javascript Async Function?

Async/Await is just syntactic sugar for promises.

They help us in the writing of asynchronous and promise-based behavior, in a cleaner and readable manner. They are built on top of the existing promises in javascript.

Promise code:

Async code:

async functions in javascript are marked with the keyword async and inside these async functions, we write promise-based code as it was synchronous. We just need to use the await operator whenever a promise is returned. This operator halts the execution of the current function until the promise is settled.

internal-working-of-async-functions

Explanation of working of an async function in javascript:

Output:

Explanation and working of the above code in depth:

  1. Foremost, a console.log() is encountered by the engine at line 11. It gets added to the main call stack after which Before function! gets logged into the console.
  2. Then myfunc() is called and hence it is pushed onto the main call stack, after this the function starts its execution. Here the engine encounters the second console.log() on line 6, which gets popped onto the main call stack, after which Before function! gets logged into the console and the function gets popped from the call stack.
  3. After that await expression is encountered inside the myfunc(); here, the function doSomething() gets into the call stack and ultimately returns a resolved promise. When this promise is resolved, and a value is returned from the function doSomething(), await is encountered. The engine immediately suspends the async function execution. The rest of the async function in javascript gets halted and is set to run inside the microtask queue.
  4. Now the engine jumps out of the async function and continues the execution of the code in the caller function. Here the engine encounters another console.log() on line 14 which gets popped into the main call stack, after which After function! gets logged into the console. Finally, the call stack is empty, and hence event loop checks to see if there are any pending tasks in the microtasks queue for execution.
  5. myfunc() again gets popped into the call stack and continues its execution where it earlier left off. The variable res gets its value from the resolved promise from doSomething(), another console.log() on line 8 is popped onto the stack, Something is printed in the console, and the async function is popped from the call stack.

Note:
There are two types of queues to manage async behavior, a micro task queue which can only contain process.nextTick(), async, and promise callbacks; second is a microtask queue which can only contain setTimeout(), setInterval(), and setImmediate().

More Examples

Async Functions and Execution Order

The sequential execution order of the async function in javascript can be explained using the following example:

Output:

In the above example, the sequential execution starts instantly and reaches line 17; after that, execution gets suspended for 2 seconds until the first function is resolved. After that, there is another delay of 1 second for the second function to resolve. So in total, the code takes 3 seconds to execute.

Await Function

The await operator causes an async function in javascript execution to pause until a promise is resolved or rejected that is fulfilled. It also resumes the execution after the execution of the promise is settled. If the promise is resolved, then the value of that awaiting expression has the value of the promise. If the promise is rejected, that value is thrown by the await expression.

After the wait delays the continuance of the async function in javascript, the execution of succeeding statements follows. If await is the last expression in the execution order, execution continues by returning to the function's caller a pending Promise for completion of the await's function and resuming execution of that caller.

Syntax:

Example:

Output:

Rewriting a Promise Chain with an Async Function

Writing an async function in javascript using the promise syntax and then chaining them can reduce the code readability, and maintaining the code can get more complex. Therefore as async await has a simpler syntax, along with its efficient error handling abilities, it seems a better solution than promises chaining.

Real-world example of Promise chaining of food order:

Now to convert it into async await we can follow the following steps:

  • Conversion of .then() calls to await:
    In the classic promise syntax, the promise was resolved using the .then() function and was rejected using the .catch() keyword. But in the new async await format, the function will be called using the await operator, which halts the execution of the current function until the called function is settled.
  • Using async keyword:
    All the function that uses await must be followed by the async keyword.
  • Error handling using the try-catch block:
    We will wrap the entire code in a try block and then catch errors if any.

Promise chain migrated to async await format code of the above example of food order:

This format of async awaits benefits over Promise Chains because of simple and flexible code, easy chaining, Efficient error handling, and no nesting of callbacks; hence layout is simplified.

Supported Browsers

Async function js statements are supported in the following browser version:

BrowserVersion
Chrome55
Edge15
Firefox52
Opera42
Safari10.1
Deno1.0
Node.js7.6.0
Samsung Internet6.0

Dive into the world of server-side JavaScript with our Node.js Free course. Enroll today and become a proficient backend developer!

Conclusion

  • Async function in javascript is a way to execute the asynchronous code synchronously and clearly.
  • Async functions are generally a combination of generators and promises, basically syntactic sugar for promises.
  • The async/await is a very useful tool for writing clean code hence helping in avoiding callback hells.
  • When a function is prefixed with async, then the function always returns a promise which can be handled by the await keyword.
  • Even if the function is not returning a promise explicitly, the engine will internally make the function return a promise.
  • Await returns the resultant value when the promise is resolved, and if the promise is rejected, the await operator throws the rejected value.
  • Await operator can only be used inside an async function.
  • The async function in javascript follows sequential order of execution.
  • Async await provides us with a way to migrate from promise chaining and maintain a readable and more manageable code using await expression and a try-catch block.