I am trying to implement my own Promise.all to prepare my interviews.
My first version is this
Promise.all = function(promiseArray) {
return new Promise((resolve, reject) => {
try {
let resultArray = []
const length = promiseArray.length
for (let i = 0; i <length; i++) {
promiseArray[i].then(data => {
resultArray.push(data)
if (resultArray.length === length) {
resolve(resultArray)
}
}, reject)
}
}
catch(e) {
reject(e)
}
})
}
However, the native Promise.all accepts not just arrays, but also any iterables, which means any object that has Symbol.iterator, such as an array or a Set or Map.
So something like this is going to work with the native Promise.all but not with my current implementation
function resolveTimeout(value, delay) {
return new Promise((resolve) => setTimeout(resolve, delay, value))
}
const requests = new Map()
requests.set('reqA', resolveTimeout(['potatoes', 'tomatoes'], 1000))
requests.set('reqB', resolveTimeout(['oranges', 'apples'], 100))
Promise.all(requests.values()).then(console.log); // it works
I modified my Promise.all by first adding a check to see if it has Symbol.iterator to make sure it is an iterable.
Promise.all = function(promiseArray) {
if (!promiseArray[Symbol.iterator]) {
throw new TypeError('The arguments should be an iterable!')
}
return new Promise((resolve, reject) => {
try {
But the challenge is with how to iterate through the iterable. Current implementation is to get the length of if and doing it with a for loop via const length = promiseArray.length however only arrays have length property on it, other iterables or iterators like Set or Map.values() will not have that property available.
How can I tweak my implementation to support other types of iterables like the native Promise.all does