create polyfill of promise.any() in javascript
this is the popular interview question in javascript where you need to create a polyfill of promise.any()
so first understand the meaning of promise.any() what it does according to mdn docs
The
Promise.any()
static method takes an iterable of promises as input and returns a singlePromise
. This returned promise fulfills when any of the input's promises fulfills, with this first fulfillment value. It rejects when all of the input's promises reject (including when an empty iterable is passed), with anAggregateError
containing an array of rejection reasons.
so what we should consider while creating pollyfill of promise any
it will take array of promises and then return a single promise which means our polyfill returns single promise
the promise which is returned form the polyfill resloves when any of the promise is resolved form array of promises
it will reject with aggregator error (which is we will return string that all promises failed) if all the promises fail or empty array is given
so let's start the polyfill solution
let's cover the first point which is we will have to make our polyfill return a promise and also it takes input of array of promises
const Promiseany = (tasks) => {
return new Promise((resolve, reject) => {
})
}
so this covers our first point we are creating a function which takes input array of promises and returns a new promise
for the second point we need to make sure when our any promise form the array of promises will resolve we will resolve our polyfill promise
const Promiseany = (tasks) => {
return new Promise((resolve, reject) => {
tasks.forEach(task => {
task.then((res) => {
resolve(res)
})
})
})
}
so here we are now looping over our promises array which is tasks it will make sure when a promise is first resolved it will resolve the main promise
for the third point if all the promises fail or an empty array is passsed we need to reject with string which will mention all promise failed
const Promiseany = (tasks) => {
let failureCount = 0; // this will keep the count of the rejected promise
return new Promise((resolve, reject) => {
// if empty array is passed it will reject
if(tasks.length === 0){
reject("All Promise rejected")
}
tasks.forEach(task => {
task.then((res) => {
resolve(res)
}).catch((err) => {
failureCount++ // increments the count of the rejected promise
// if the rejected promises is equal to tasks length which is passed array of promise
if(failureCount === tasks.length){
reject("All Promise rejected")
}
})
})
})
}
so here we keep the count of the rejected promise in the variable failureCount
it will be incremented in the catch block of each promise if it fails and finally when failure count is equals to tasks length which is basically the array of promise which is passed to our promiseany it will be rejected with error('All promise rejected')
there is also case handled for the empty array so when the tasks array length is zero we will reject with error('All promise rejected')
so here is the full implementation of our polyfill
const Promiseany = (tasks) => {
let failureCount = 0;
return new Promise((resolve, reject) => {
if(tasks.length === 0){
reject("All Promise rejected")
}
tasks.forEach(task => {
task.then((res) => {
resolve(res)
}).catch((err) => {
failureCount++
if(failureCount === tasks.length){
reject("All Promise rejected")
}
})
})
})
}
const pErr = new Promise((resolve, reject) => {
reject("Always fails");
});
const pSlow = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "Done eventually");
});
const pFast = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "Done quick");
});
Promiseany([pErr,pSlow,pFast]).then(res => console.log(res)).catch(err => console.error(err))
// Expected Output : Done quick
when all promises are rejected
const Promiseany = (tasks) => {
let failureCount = 0;
return new Promise((resolve, reject) => {
if(tasks.length === 0){
reject("All Promise rejected")
}
tasks.forEach(task => {
task.then((res) => {
resolve(res)
}).catch((err) => {
failureCount++
if(failureCount === tasks.length){
reject("All Promise rejected")
}
})
})
})
}
const pErr = new Promise((resolve, reject) => {
reject("Always fails");
});
const pSlow = new Promise((resolve, reject) => {
setTimeout(reject, 500, "Done eventually");
});
const pFast = new Promise((resolve, reject) => {
setTimeout(reject, 100, "Done quick");
});
Promiseany([pErr,pSlow,pFast]).then(res => console.log(res)).catch(err => console.error(err))
// Expected output : All Promise rejected
when empty array is passed
const Promiseany = (tasks) => {
let failureCount = 0;
return new Promise((resolve, reject) => {
if(tasks.length === 0){
reject("All Promise rejected")
}
tasks.forEach(task => {
task.then((res) => {
resolve(res)
}).catch((err) => {
failureCount++
if(failureCount === tasks.length){
reject("All Promise rejected")
}
})
})
})
}
Promiseany([]).then(res => console.log(res)).catch(err => console.error(err))
// Expected results : All Promise rejected
conclusion :- so this it folks thanks for reading till end hope my explanation was clear if any suggestion comment down below