This post will QUICKLY cover the basics of promises then go into the other side of promises rarely talked about(Promise.all(),Promise.allSettled(), Promise.race(), Promise.any()). Great way to discover more uses for promises and impress that interviewer at some point. If you prefer a video version please check out...
JUNIOR DEV LEVEL
Ok so if this isn't the first time you seen Promises feel free to skip to next section. Here is the summary of what a promise is in JS. Promises give us a better way to handle callbacks and more notably the callback hell that many talk about.
Simplified: With more then one callback a pattern that made it difficult to read and maintain JS such as this beauty...
Call Back Hell Example
callOne(args, () => {
// Wait for One then call Two
callTwo(args, () => {
// Wait for Two then call Three
callThreeRejected(args, () => {
})
})
})
Functions used in examples
let callOne = new Promise((res, rej) => {
return setTimeout(res, 3000, "Call One Returned")
})
let callTwo = new Promise((res, rej) => {
return setTimeout(res, 2000, "Call Two Returned")
})
let callThreeRejected = new Promise((res, rej) => {
return setTimeout(rej, 1000, "Call Three REJECTED")
})
Common usage chaining promises in sequence
callOne
.then(data => {console.log(data); return callTwo})
.then(data => {console.log(data); return callThreeRejected})
.then(data => {console.log(data)})
.catch(err => console.error(err))
//With Async / Await
async function useAsync(){
const dataOne = await callOne
console.log(dataOne)
const dataTwo = await callTwo
console.log(dataTwo)
const dataThree = await callThreeRejected.catch((e) => {
console.error(e)})
console.log(dataThree)
}
useAsync()
console.log
"Call One Returned"
"Call Two Returned"
"Call Three REJECTED"
SENIOR DEV LEVEL
Promise.all([getDataOne, getDataTwo, getDataThree])
Summary:Returns array of all promise data UNLESS one is rejected. Should be named to Promise.allOrNothing()
USE CASE: When results from more then one API call are needed to do something with(display in a ChartJS graph). This makes sense since if one call is rejected the chart cannot be built correctly.
let consumeParallel = async () => {
let [resultsOne, resultsTwo] = await Promise.all([callOne, callTwo])
// Use for error handling and comment out prev 7 lines
// let [resultsOne, resultsTwo, resultsThree] = await Promise.all([callOne, callTwo, callThreeRejected]).catch(err => console.error(err))
console.log(`All Promises: ${resultsOne} && ${resultsTwo}`)
}
consumeParallel()
console.log
"All Promises: Call One Returned Call Two Returned"
Promise.allSettled([getDataOne, getDataTwo, getDataThree])
Summary:Wait for no more pending promises (all settled) meaning each either resolved or rejected.
USE CASE: Seemingly few use cases for this (if you have others put in comments please). One that is consistent is using this for indicating when a displayed loader/spinner should be removed from screen.
let consumeSettled = () => {
Promise.allSettled([callOne, callTwo, callThreeRejected])
.then(promiseResults => console.log(promiseResults))
.catch(e => console.error(e))
}
consumeSettled()
console.log
[
{status:"fulfilled", value:"call one returned"},
{status:"fulfilled", value:"call two returned"},
{status:"rejected", reason:"call three REJECTED"}
]
Promise.race()
Summary: Takes in iterable such as an array and returns data for the first settled (resolved or rejected) promise.
USE CASE:An interesting use case for .race() is having one promise along with another that resolves with a certain time period in ms and if that one resolves first show a loader/spinner.
let racePromises = async () => {
let firstDone = await Promise.race([callOne, callTwo])
console.log(`First Promise Settled: ${firstDone}`)
}
racePromises()
console.log
First Promise Settled: Call Two Returned
Promise.any()
Summary: Takes in iterable such as an array and returns data for the first resolved promise.
USE CASE:For a performance use case a developer can use .any() to set up an array of promises if the users are worldwide and more than one server is available. This would allow for the fastest response time from a server.
let anyPromise = async () => {
let firstDone = await Promise.any([callOne, callTwo])
console.log(`First Resolved: ${firstDone}`)
}
anyPromise()
console.log
"First Resolved: Call Two Returned"
There you go. Hope this helps at least one person see the potential of using promises and the built in methods it allows.
Top comments (0)