Async/Await
Inside a function marked as async, you are allowed to place the await keyword in front of an expression that returns a Promise. When you do, the execution is paused until the Promise is resolved.
Before we dive into it, let’s take a moment to familiarize you with the async/await style. First, async/await makes the asynchronous code appear and behave like synchronous code. Being that it was built on top of Promises, you could simply see it as a new way of writing synchronous code. Just like Promises themselves, async/await is equally non-blocking.
The purpose of async/await functions is to simplify the behavior of using Promises synchronously and to perform some behavior on a group of Promises. Just as Promises are similar to structured callbacks, one can say that async/await is similar to combining generators and Promises.
Basically, there are two keywords involved, async and await, let’s understand them better:
Async
Putting the keyword async before a function tells the function to return a Promise. If the code returns something that is not a Promise, then JavaScript automatically wraps it into a resolved promise with that value e.g when it returns an AsyncFunction object:
async function oddNumber() {
return 7;
}
Then it’ll return a resolved Promise with the result of 7, however, we can set it to explicitly return a Promise like this:
async function evenNumber() {
return Promise.resolve(8);
}
Then there’s the second keyword await that makes the function even much better.
Await
The await keyword simply makes JavaScript wait until that Promise settles and then returns its result:
let result = await promise;
Note that the await keyword only works inside async functions, otherwise you would get a SyntaxError. From the async function above, let’s have an await example that resolves in 2secs.
async function evenNumber() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("8"), 2000)
});
let result = await promise; // pause till the promise resolves
alert(result); // "8"
}
await simply makes JavaScript wait until the Promise settles, and then go on with the result. Meanwhile, as it waits, the engine carries on with performing other tasks like running scripts and handling events. Thus, no CPU resources will be lost.
Syntax
async function name([param[, param[, ... param]]]) {
statements
}
Return Value
Now that you have a fair understanding of how async/await works and it’s syntax, let’s go ahead and dive into more awesome features that will convince you to adopt it:
Example : 2
//Async Await
"use strict"
function wait10secs(){
return new Promise((resolve)=>{
setTimeout(()=>resolve("waitOver"),10000)
})
}
async function callWait(){
console.log("Async Started")
let result = await wait10secs(); //stop execution till wait10secs is finished
console.log("Result:",result)
console.log("Async Finished")
}
callWait()
Example : fetch-reject-promise-and-catch-the-error-if-status-is-not-ok
Fetch promises only reject with a TypeError when a network error occurs. Since 4xx and 5xx responses aren’t network errors, there’s nothing to catch. You’ll need to throw an error yourself to use Promise#catch.
A fetch Response conveniently supplies an ok , which tells you whether the request succeeded. Something like this should do the trick:
function _getSSID() {
console.log('From _getSSID')
return new Promise((resolve, reject) => {
fetch('https://jsonplaceholder.typicode.com/posts/1 jk')
.then(response => {
//Handle Error
if(response.ok){
return response.json()
} else {
throw new Error('Something went wrong');
}
})
//.then(response => {response.json()})
.then(json => resolve(json.title))
.catch((error) => { console.log('I am from reject fetch '); reject(error)})
})
}
async function getSSID() {
try {
let mySSID = await _getSSID()
console.log('mySSID :', mySSID)
} catch (e) {
console.log("Await Error : ", e.message)
}
}
console.log('Before the Async Await')
getSSID().catch((e)=>{console.log('Error : ', e)});
console.log('After the Async Await')
console.log('*********************')
//OUTPUT
Before the Async Await
From _getSSID
After the Async Await
*********************
I am from reject fetch
Await Error :
Something went wrong
Example 1 – //If we use “async” keyword before the function name, it will return promise
async function foo(){
return 1;
}
console.log(foo())
Example 2
async function foo(){
return 1;
}
foo().then(
(data)=>{console.log(data)
})
Example 3 –
// await is similar to using then in promise
// Can not return value from async function
async function foo(){
let promise = new Promise(function(resolve, reject){
setTimeout(function(){
resolve(100)
}, 1000)
})
let result = await promise;
// return result
console.log(result)
}
console.log(foo())
Example 4
async function foo(){
let response = await fetch("https://jsonplaceholder.typicode.com/todos/1")
console.log("response : ", response)
let result = await response.json();
console.log("async : ", result)
}
foo()
Example 5 – Alternet to “Ex.5”
async function foo(){
let response = await fetch("https://jsonplaceholder.typicode.com/todos/1")
console.log("response : ", response)
let result = await response.json();
console.log("async : ", result)
return result
}
foo().then((result)=>{console.log("Result : ",result)});
Example 6 – By default “fetch” api will return promise , we have to get through the “then” part
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(" fetch Api : ", json))
Function returns promise object instead of value (async/await)
Declare a function async means that it will return the Promise. To turn the Promise into a value, you have two options.
The “normal” option is to use then() on it:
getSSID().then(value => console.log(value));
You can also use await on the function:
const value = await getSSID();
The catch with using await is it too much be inside of an async function.
At some point, you’ll have something at the top level, which can either use the first option, or can be a self-calling function like this:
((async () => {
const value = await getSSID();
console.log(value);
})()).catch(console.error)
If you go with that, be sure to have a catch() on that function to catch any otherwise uncaught exceptions.
You can’t use await at the top-level.
Different way of doing function call – Nested, Promise, Async/await
var fs = require('fs')
var myObj = {}
fs.readFile('file1.txt', function (err, data) {
if (!err) {
myObj['data1'] = data.toString()
}
})
fs.readFile('file2.txt', function (err, data) {
if (!err) {
myObj['data2'] = data.toString()
}
})
console.log(myObj)
//2. Nested Callback
var fs = require('fs')
var myObj = {}
fs.readFile('file1.txt', function (err, data) {
if (!err) {
myObj['data1'] = data.toString()
fs.readFile('file2.txt', function (err, data) {
if (!err) {
myObj['data2'] = data.toString()
console.log(myObj)
}
})
}
})
//3. Using Promise
var fs = require('fs')
var myObj = {}
function doA() {
return new Promise(function (resolve, reject)){
fs.readFile('file1.txt', function (err, data) {
if (!err) {
resolve(data.toString())
}
})
}
}
function doA() {
return new Promise(function (resolve, reject)){
fs.readFile('file2.txt', function (err, data) {
if (!err) {
resolve(data.toString())
}
})
}
}
doA().then(function (data) {
myObj['data1'] = data;
doB().then(function (data) {
myObj['data2'] = data2
console.log(myObj)
})
})
//3. Using Async / await
async function main() {
myObj['data1'] = await doA();
myObj['data2'] = await doB();
console.log(myObj)
}
main()
//OutPut
{ data1: 'This is file 1', data2: 'and thiss if file 2' }
How to return values from async functions using async-await from function?
You cant await something outside async scope. To get expected result you should wrap your console.log into async IIFE i.e
async function getData() {
return await axios.get('https://jsonplaceholder.typicode.com/posts');
}
(async () => {
console.log(await getData())
})()
Since axios returns a promise the async/await can be omitted for the getData function like so:
function getData() {
return axios.get('https://jsonplaceholder.typicode.com/posts');
}
and then do same as we did before
(async () => {
console.log(await getData())
})()
Reference
-
async-await – javascript.info
- Sitepoint
- Pusher Syntax
- Examples
- Codeburst
- Codeburst Promise
- hackernoon
- Medium
Zellwk
JavaScript async and await in loops
Promises
async-await-vs-promises
Playing with promises and async/await Code Sample