First added in ES2017 and maybe in the near future they will become the most used keywords for handling promises.
Let’s start with async and then move on with await.
It’s placed before any function definition that returns a promise, if there is no promise to be returned then the output will be wrapped in Promise.resolve(
Ex:
const fct = async () => true;
fct().then(console.log);
Even though we are not returning any promise we can use the then
to pass a callback and retrive the actual result.
const fct = async () => Promise.resolve(true);
fct().then(console.log);
The above snippets of code are equivalent.
Until now we can recap that async is only placed before a function and that function will always return a promise.
Moving on to await..
const waitForIt = async () => {
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 1000);
});
return await promise;
};
waitForIt().then(value => {
console.log(value);
});
Using await will really make javascript engine wait until the promise is resolved and then move on with the execution of that function switching context to other scripts or functions.
However await can’t be used in non async function:
function a(){
const result = await fetch(...);
}
Example above will not work unless we add async in front on the function keyword.
Let’s recap about await keyword.
It can only be used in async functions and placed only before a promise object.
Objects that have then function can be used with await keyword:
class ThenableClass {
then(resolve, reject) {
resolve(12312);
}
}
const thenableObject = new ThenableClass();
const thenFunction = async () => await thenableObject;
thenFunction().then(console.log);
That’s it, now you have your own custom object on which you can use the await keyword.
In the same manner you can create an async function and use it exactly as you are using any other async function.
class ThenableClass {
then(resolve, reject) {
resolve(12312);
}
async myAsync() {
return 3231;
}
}
thenableObject.myAsync().then(console.log);
async rejectPromise() {
try {
let f = async () => Promise.reject(new Error("reject"));
let response = await f();
} catch (err) {
console.log(err);
}
}
In above example you can see that handling rejection is pretty simple, just wrap your await keyword in try/catch blocks and you’re ready to go.