“Async/Await” syntax for better “Promise”

“Async/Await” syntax for better “Promise”

Introduction

asyn/await

Using only one promise is clear and simple, but when the program is complicated by asynchronous logic, working with promises quickly becomes difficult. With the ES2017 standard, a new syntax “async/await” has arrived, which makes it easier to work with promises, and enables a simpler presentation of a series of asynchronous promises. Using the “async/await” syntax allows us to display multiple interdependent asynchronous actions more readably and thus avoid the so-called “promise hell”. It should be noted that “ordinary” callback functions cannot be used with async functions.

“Async/await” syntax does not exclude promises, but changes the way of “consumption” of promises. Async/Await syntax allows us to write asynchronous code according to the sequential order of execution so that it looks like synchronous code.

Asynchronous Function Syntax

Marking the function with “async”

An asynchronous function is a function within which asynchronous code is executed. An asynchronous function is marked with the “async” keyword. A function marked like this lets the compiler know that an asynchronous operation will be performed inside it.

The tasks that the async function performs in the background are:

  1. Automatically converts a regular function to a promise
  2. Anything returned with “return” in the function body becomes “Promise.resolve” after a successful operation

    An Async function always returns a “promise”, even if the returned value is not a “promise”. The async function “wraps” each returned value and passes it as a Promise.
  3. Async function allows using await operator.

“Await” operator

This operator can only be used within the “async” function, where it pauses the execution of the async function. The reserved word “await” pauses the execution of the async function until it receives the results of the operation ie. until the promise is returned. If the Promise is in the state fulfilled, then the result that “awaited” the await has the “fulfillment” value, and if the promised Promise is in the “rejected” state, then the await forwards the “rejection” value.

Error handling

The standard try/catch syntax is used with the await operator. The await operator “waits” for a promise, and if the operation is successful, the async function returns “promise resolved”. In case of an unsuccessful operation, it passes “promise rejected”, while the “catch” block is used to “catch” that “exception”.



Explanation:
Using async/await syntax allows javascript to better manage errors (especially stack trace), and to use memory in a more efficient way (eng. memory-efficient).

Parallelism

Async operations are executed in series one after the other, so they should not be confused with “Promise.all” where promises are executed in parallel. For parallel execution of promises, it is best to use “Promise.all” syntax. It should be emphasized that the “async/await” syntax does not exclude the “promise.all” syntax, even more together they give their maximum and the code is clear and reviewed. The following examples will show the difference between serial and parallel execution.

Serial execution

This is an example of batch execution because another “await” is waiting for the first operation to be executed.

Parallel execution

If we want the operations to be executed in parallel, we need to let both functions be executed in parallel, and only then “wait” for them with the await operator:

Symbiosis of Promise.all and async/await syntax

With destructuring we can assign the returned values individually:

Iteration of asynchronous operation

for…of

It is recommended to use a “for…of” loop for iteration in an asynchronous function:

Problems with array iteration methods

A method for iterating through arrays, such as “forEach()” cannot be used with async/await syntax. Using the “await” operator inside a method throws an error, and the error occurs because the “await” operator can only exist within an async function, and in this case it would be within the forEach() method.

Even if within forEach() the anonymous callback function was defined as asynchronous, it would only help that it does not throw an error, but it would not give the expected result, because the “forEach” method does not “wait” for an asynchronous operation, but continues the execution of synchronous code.

Examples of using Async/Await syntax

This section describes the process of switching the syntax from “plain” promises to the new improved Async/Await syntax.

Individual asynchronous operations

a) Simple asynchronous operation



b) XMLHttpRequest()

In this example they are shownsnippets for getting data in the form of JSON, in two ways: the first one using HMLHttpRequest() and Promise and the second one where the new Async/Await syntax is applied.



c) fetch()



A series of sequential promises



A series of sequential interdependent promises

All the advantages and improvements brought by the new syntax can best be seen in this example. First, a series of linked promises with only promises (without Async/Await) is shown:



A series of multiple parallel asynchronous operations