The async
and await
keywords help us in handling Promises in a more convenient way and it is more readable than regular promise handling using then()
and catch()
.
Let’s see how we consume Promises using .then()
and .catch()
.
let flag = true; let promise = new Promise((resolve, reject) => { setTimeout(() => { if(flag) resolve('I am resolved'); else reject(new Error('I am rejected')); }, 1000); }); promise.then(res => console.log(res)).catch(err => console.log(err)); // I am resolved
The above Promise can be consumed by using async
and await
like below.
async function demo() { let promise = new Promise((resolve, reject) => { setTimeout(() => { resolve('I am resolved'); }, 1000); }); let res = await promise; console.log(res); // I am resolved } demo();
The
await
keyword should only be used inside anasync
function.
The async keyword
If we use async
before any function then the function will return a Promise. If the function is not returning any Promise explicitly then it will wrap a Promise around the return value implicitly. Let’s see one example.
async function greet() { return 'Welcome'; } greet().then(res => console.log(res)); // Welcome
The await keyword
The await
keyword waits for a Promise and pauses the code in that line until the Promise gets resolved. Remember the await keyword should always be used inside async
function otherwise, it will throw an error.
async function foo() { let promise = new Promise((resolve, reject) => { setTimeout(() => { resolve('I am resolved'); }, 1000); }); let res = await promise; console.log(res); console.log('end'); } foo(); // I am resolved // end
Here the code execution gets paused in the line where await
is used and resumes when the Promise resolves. Therefore after 1 second when the Promise will resolve, the console statements will be printed.
Handling Errors
We can use the try…catch block to handle errors in async
/ await
.
async function foo() { let promise = new Promise((resolve, reject) => { setTimeout(() => { reject(new Error('I am rejected')); }, 1000); }); try { let res = await promise; console.log(res); } catch (e) { console.log(e); } } foo(); // Error: I am rejected
The async
and await
keywords also work for methods like Promise.all
and Promise.race
.
Promise.all()
The Promise.all()
method takes an iterable of promises as an input and returns a single Promise and it gets resolved when all the promises get resolved or any one of them gets rejected.
function getPromise(delay) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(delay + 100); }, delay); }); } async function foo() { const results = await Promise.all([ getPromise(1000), getPromise(3000), getPromise(2000), ]); console.log(results); } foo(); // [1100, 3100, 2100]
Promise.race()
The Promise.race()
method takes an iterable of Promises and returns a Promise which gets resolved/rejected as soon as any of the Promises resolved or rejected.
async function foo() { let promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('Promise 1'); }, 1000); }); let promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('Promise 2'); }, 500); }); const result = await Promise.race([promise1, promise2]); console.log(result); // Promise 2 } foo();
Wow! You must have got a clear idea about async
and await
by now. Let’s take the order process example from the Promise article and rewrite using async
and await
.
function takeOrder() { return new Promise((resolve, reject) => { setTimeout(() => { const order = (Math.random() * 10) <= 5 ? 'Coffee' : 'Tea'; resolve(order); }, 1000); }) } function makeOrder(order) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(order + ' is prepared'); }, 1000); }) } function serveOrder(order) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(order + ' is served'); }, 1000); }) } async function orderProcess() { try { const order = await takeOrder(); console.log('Order is for: ' + order); let orderMakingStatus = await makeOrder(order); console.log(orderMakingStatus); let orderServingStatus = await serveOrder(order); console.log(orderServingStatus); } catch (error) { console.log(error); } } orderProcess(); // Order is for: Tea // Tea is prepared // Tea is served
References
Web Developer by Profession, Blogger by Passion.
JavaScript | React | Next | Angular | Vue | HTML | CSS