You may have heard that async
and await
is a syntactic sugar for promises. Promise works perfectly for asynchronous tasks such as I/O operations, API calls etc... So why do we need async
and await
Issues with Promise
Readability
Consider the following snippet
const sleep = (delay) =>
new Promise((resolve) => setTimeout(() => resolve(`sleep ${delay}`), delay));
const result = sleep(1000)
console.log(result);
sleep -> promise that resolves after given delay
When you try to run the code, the expected output is
sleep 1000
Instead
Promise { <pending> }
To get the expected result you have to do the following change
sleep(1000).then(console.log)
The issue with this is, the task that needs to be executed after fulfilling the promise needs to written in the then
block. This means whatever written after promise will be executed before the then
block. This may cause confusion because the execution of the code is not linear.
Error handling
Promise gives pretty good API to handle the error situations. Errors can be handled in the catch
block just like then
block. The traditional try, catch
will not work in case of promise since execution of promise is after executing the try and catch
Async and await
Async and await introduced to JavaScript in ECMA 2017, which helps to resolve the above issues. The code become linear and try catch
can be used to handle the errors
const sleep = (delay) =>
new Promise((resolve) => setTimeout(() => resolve(`sleep ${delay}`), delay));
async function asyncFunc() {
try {
const result = await sleep(1000);
console.log(result)
} catch (e) {
console.log(e);
}
}
asyncFunc()
When you are using await
, it will wait for the promise to either resolve or reject, then only the next line executes. The above snippet looks simple JavaScript except two weird keywords :D
await
only can be used inside anasync
function
Implementation of async await with generator
Few things to consider
-
await
is added before a promise - Next line is executed after completing the promise
const sleep = (delay) =>
new Promise((resolve) => setTimeout(() => resolve(`sleep ${delay}`), delay));
function awaitFunc(promise) {
promise.then((res) => iterator.next(res));
}
function* asyncFunc() {
try {
const result1 = yield awaitFunc(sleep(1000));
console.log(result1);
const result2 = yield awaitFunc(sleep(2000));
console.log(result2);
} catch (error) {
console.log(error);
}
}
var iterator = asyncFunc();
iterator.next();
The above snippet give exact result as async
and await
In here consider
-
awaitFunc
accepts a promise and resolve and let generator continue the execution -
function*
to beasync
-
yeild
andawaitFunc
to be await
Top comments (0)