Skip to content

Instantly share code, notes, and snippets.

@Guseyn
Last active April 16, 2019 06:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Guseyn/30f7f9c1ec12e369db0ee490c1c96dad to your computer and use it in GitHub Desktop.
Save Guseyn/30f7f9c1ec12e369db0ee490c1c96dad to your computer and use it in GitHub Desktop.
mapLimit via callbacks
function mapLimit (col, limit, mapFunc, doneFunc, newCol = [], index = { value: 0 }, freeThreads = { value: limit }) {
if (freeThreads.value > 0 && index.value < col.length) {
// Save current index
const curIndex = index.value
// Now the number of free threads is lower on 1
freeThreads.value -= 1
mapFunc((err, newItem) => {
if (err) {
// Smth bad happend, we call doneFunc with err
doneFunc(err, newCol)
} else {
newCol[curIndex] = newItem
// We can now free one thread
freeThreads.value += 1
if (curIndex === col.length - 1) {
// If we processed all elements, we can call doneFunc
doneFunc(null, newCol)
} else if (freeThreads.value > 0) {
// if we have free threads, we can call again mapLimit with increased value of index on 1
index.value += 1
mapLimit(col, limit, mapFunc, doneFunc, newCol, index, freeThreads)
}
}
}, col[curIndex])
if (freeThreads.value > 0 && curIndex < col.length) {
// if we have free threads, we can call again mapLimit with increased value of index on 1
index.value += 1
mapLimit(col, limit, mapFunc, doneFunc, newCol, index, freeThreads)
}
}
}
// Let's test this solution now
const startDate = new Date()
// Let's create a collection
let col = []
for (let i = 0; i < 16; i++) {
col.push(i)
}
console.log('Input collection is ', col) // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]
// Our mapFunc
function makeNumbersNegativeAsyncCall(cb, item) {
setTimeout(function() {
newItem = item * -1
cb(null, newItem)
}, 200);
}
// Let's try with limit = 2
mapLimit(col, 2, makeNumbersNegativeAsyncCall, (err, newCol) => {
console.log(`Solution with limit = 2, time is ${new Date().getTime() - startDate.getTime()}ms and output collection is`, newCol) // 1623ms
})
// Let's try now with limit = 8, should be faster
mapLimit(col, 8, makeNumbersNegativeAsyncCall, (err, newCol) => {
console.log(`Solution with limit = 8, time is ${new Date().getTime() - startDate.getTime()}ms and output collection is`, newCol) // 411ms; yes, it's faster
})
Input collection is  [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]
Solution with limit = 8, time is 411ms and output collection is [ -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15 ]
Solution with limit = 2, time is 1623ms and output collection is [ -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15 ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment