Promise
An object used for asynchronous operations. These objects have a state of either pending
, fulfilled
or rejected
. A Promise is created with the Promise()
constructor, which takes in a callback function, oftentimes called the executor.
This callback function has two callback functions as parameters:
resolve(value)
: Fulfills the Promise and sets its value.reject(error)
: Rejects the Promise and sets an error message.
The Promise object has three primary functions:
then(fulfilledFn, rejectedFn)
: Calls fulfilledFn if the Promise is fulfilled and rejectedFn if it is rejected. Returns a new fulfilled Promise with the return value of the callback function.catch(rejectedFn)
: Calls rejectedFn if the Promise is rejected. Returns a new fulfilled Promise with the return value of the callback function.finally(callback)
: Calls the callback function whenever the Promise is settled (fulfilled or rejected).
Since these functions all return a new Promise, they can be chained together, such as in this example below:
const errorProm = new Promise((resolve, reject) => {
reject("There has been a data breach!");
});
errorProm
.then((val) => console.info(val))
.catch(err => {
console.info(`Error: ${err}`);
})
.finally(() => console.info('Promise fulfilled'));
The console output will be:
Error: There has been a data breach!
Promise fulfilled
This is because we rejected the Promise, so the then
function is skipped and the catch
function is executed and then finally, the finally
function gets executed.
Did you see what I did there;)
async function
An async function is a function declared with the async
keyword, and the await
keyword is permitted within it. The async
and await
keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains.
In other words, async
/await
help us write our asynchronous code in a synchronous style.
await
A keyword indicating that JavaScript should wait for a Promise to settle before continuing execution of the code. Traditionally this is only available in async
functions, but it can also be used at the top level of modules
.
refactor Promise style code with async/await
An API call that returns a Promise
will result in a promise chain, and it splits the function into many parts.
Consider the following code:
function getProcessedData(url) {
return downloadData(url) // returns a promise
.catch(e => {
return downloadFallbackData(url) // returns a promise
})
.then(v => {
return processDataInWorker(v) // returns a promise
})
}
This can be rewritten with a single async
function as follows:
async function getProcessedData(url) {
let data;
try {
data = await downloadData(url);
} catch(err) {
data = await downloadFallbackData(url);
}
return processDataInWorker(data);
}
You can also chain the promise with catch()
:
async function getProcessedData(url) {
const data = await downloadData(url).catch(err => {
return downloadFallbackData(url);
});
return processDataInWorker(data);
}