Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 2x 8x 8x 8x 8x 8x 8x 8x 8x 67x 2x 65x 65x 65x 65x 16x 16x 6x 16x 49x 49x 49x 49x 2x 2x 49x 49x 49x 8x 18x 18x 2x 2x | /**
* Execute an async function over an iterable collection
*
* @async
* @function mapper
* @param {*} iterable- An iterable collection
* @param {function} mappingFunction - The async mapping function to execute
* @param {number} [concurrency=Infinity] - The max number of concurrent calls
* @returns {*} - The mapped results
* @example
*
* const results = await mapper(
* [1,2,3,4,5],
* asyncFunction
* )
*/
const mapper = (iterable, mappingFunction, concurrency = Infinity) =>
new Promise((resolve, reject) => {
const results = []
const iterator = iterable[Symbol.iterator]()
let isRejected = false
let isIterableComplete = false
let resolvingCount = 0
let currentIndex = 0
const next = () => {
if (isRejected) {
return
}
const nextItem = iterator.next()
const i = currentIndex
currentIndex++
if (nextItem.done) {
isIterableComplete = true
if (resolvingCount === 0) {
resolve(results)
}
return
}
resolvingCount++
return Promise.resolve(nextItem.value)
.then(async element => {
try {
return await mappingFunction(element, i)
} catch (err) {
isRejected = true
return reject(err)
}
})
.then(value => {
results[i] = value
resolvingCount--
return next()
})
}
for (let i = 0; i < concurrency; i++) {
next()
if (isIterableComplete) {
break
}
}
})
module.exports = mapper
|