Async/Await in JavaScript: examples
Using asynchronous functions synchronously when necessary is now possible...
The rules for using this feature are as follows:
- If the call to a function is preceded by the reserved word await, instructions that follow this call are not executed until the function returns a value. This is the principle of synchronous mode.
- await can only be placed in a function, and this function must be declared with the reserved word async. (It may be the main function that contains the entire program).
- The function called must be executed inside the body of a Promise object. This object can be placed in the function called or it is the call of the function that must be placed in it, at your choice.
The syntax is as follows:
function f1() {
... body of the function called...
}
async function f2() {
var x = await new Promise(function(resolve) {
resolve( f1() )
} );
...following instructions, using x...
}
f2()
The resolve parameter is a callback, and the return value of this function will be the return value of f2.
This syntax is appropriate with the functions of a library which can not be modified.
The alternative if you can modify the function called:
function f1() {
return new Promise(function(resolve) {
... body of the function called...
});
}
async function f2() {
var x = await f1()
... following instructions, using x...
}
f2()
This alternative is appropriate when we define ourselves the functions and want them to be synchronous.
It should be noted that while the instructions following the call of f1 in f2 are not executed before the return of f1, this is not the case of the instructions which follow the call of f2. They will be executed before the return of f1 and f2.
Example with an asynchronous function
The setTimeout command is there only for the demo, to add a delay and to verify that we are waiting for the return of the call before executing the following statements, in this case before displaying the result of the calculation of the Fibonacci suite.
function fibo(n) {
if (n < 2) return n
return fibo(n-2) + fibo(n-1)
}
async function getFibo(n) {
var f = await new Promise(function(resolve) {
setTimeout(function() { resolve(fibo(n)) }, 2000)
});
document.getElementById("storage1").innerHTML = ("Fibo=" + f)
}
getFibo(20)
If you did not add await, the command to display the result would have shown undefined or Object[Promise]instead.
Example with an synchronous function
This time we place the Promise object in the function called, it will be more practical if we call it several times.
function fibo(n) {
if (n < 2) return n
return fibo(n-2) + fibo(n-1)
}
function pFibo(n) {
var p = new Promise(
function(resolve) {
setTimeout(function() { resolve(fibo(n)) }, 1000)
}
)
return p
}
async function getFibo(n) {
var f = await pFibo(n)
document.getElementById("storage2").innerHTML = ("Fibo=" + f)
}
getFibo(20)
We can not place the Promise object directly in Fibo which is a recursive function, it is why we create an intermediate function. The same will be done for the functions of a library which can not be modified.
See also :
- Promise. Chaining Promises is more readable than nesting callbacks.
- JavaScript without callback. Async/await is one way to avoid nested callbacks.