Skip to content

Instantly share code, notes, and snippets.

@wavded
Last active February 24, 2021 14:08
Show Gist options
  • Star 33 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save wavded/6116786 to your computer and use it in GitHub Desktop.
Save wavded/6116786 to your computer and use it in GitHub Desktop.
function map (arr, func) {
return Promise.resolve().then(function () {
return arr.map(function (el) { return func(el) })
}).all()
}
function mapSeries (arr, func) {
let currentPromise = Promise.resolve()
let promises = arr.map(function (el) {
return currentPromise = currentPromise.then(function () {
return func(el)
})
})
return Promise.all(promises)
}
function mapLimit (arr, limit, func) {
let batches = arr.reduce(function (last, next, index) {
if (index % limit == 0) last.push([next])
else last[last.length-1].push(next)
return last
}, [])
let currentPromise = Promise.resolve()
let promises = batches.map(function (batch) {
return currentPromise = currentPromise.then(function () {
let batchPromises = batch.map(function (el) { return func(el) })
return Promise.all(batchPromises)
})
})
return Promise.all(promises)
.then(function (results) {
return Array.prototype.concat.apply([], results) // flatten array
})
}
function filter (arr, func) {
let promises = arr.map(function (el) { return func(el) })
return Promise.all(promises).then(function (results) {
return arr.filter(function (el,i) { return results[i] })
})
}
function filterSeries (arr, func) {
let currentPromise = Promise.resolve()
let promises = arr.map(function (el) {
return currentPromise = currentPromise.then(function () {
return func(el)
})
})
return Promise.all(promises).then(function (results) {
return arr.filter(function (el,i) { return results[i] })
})
}
function reject (arr, func) {
let promises = arr.map(function (el) { return func(el) })
return Promise.all(promises).then(function (results) {
return arr.filter(function (el,i) { return !results[i] })
})
}
function rejectSeries (arr, func) {
let currentPromise = Promise.resolve()
let promises = arr.map(function (el) {
return currentPromise = currentPromise.then(function () {
return func(el)
})
})
return Promise.all(promises).then(function (results) {
return arr.filter(function (el,i) { return !results[i] })
})
}
function reduce (arr, initialVal, func) {
let currentPromise = Promise.resolve(initialVal)
arr.map(function (el) {
return currentPromise = currentPromise.then(function (memo) {
return func(memo, el)
})
})
return currentPromise
}
function reduceRight (arr, initialVal, func) {
let currentPromise = Promise.resolve(initialVal)
arr.reverse().map(function (el) {
return currentPromise = currentPromise.then(function (memo) {
return func(memo, el)
})
})
return currentPromise
}
function detect (arr, func) {
let promises = arr.map(function (el) { return func(el) })
return Promise.all(promises).then(function (results) {
return arr.filter(function (el,i) { return results[i] }).shift()
})
}
function detectSeries (arr, func) {
let currentPromise = Promise.resolve()
let promises = arr.map(function (el) {
return currentPromise = currentPromise.then(function () {
return func(el)
})
})
return Promise.all(promises).then(function (results) {
return arr.filter(function (el,i) { return results[i] }).shift() // could be optimized to return first
})
}
function sortBy (arr, func) {
let promises = arr.map(function (el) { return func(el) })
return Promise.all(promises).then(function (results) {
return arr.sort(function (a, b) {
return results[arr.indexOf(a)] < results[arr.indexOf(b)] ? -1 : 1
})
})
}
function some (arr, func) {
let promises = arr.map(function (el) { return func(el) })
return Promise.all(promises).then(function (results) {
return results.some(function (el) { return el })
})
}
function every (arr, func) {
let promises = arr.map(function (el) { return func(el) })
return Promise.all(promises).then(function (results) {
return results.every(function (el) { return el })
})
}
function concat (arr, func) {
let promises = arr.map(function (el) { return func(el) })
return Promise.all(promises).then(function (results) {
return Array.prototype.concat.apply([], results) // flatten results
})
}
function concatSeries (arr, func) {
let currentPromise = Promise.resolve()
let promises = arr.map(function (el) {
return currentPromise = currentPromise.then(function () {
return func(el)
})
})
return Promise.all(promises).then(function (results) {
return Array.prototype.concat.apply([], results) // flatten results
})
}
function parallel (funcs) {
let promises = funcs.map(function (func) { return func() })
return Promise.all(promises)
}
function series (funcs) {
let currentPromise = Promise.resolve()
let promises = funcs.map(function (func) {
return currentPromise = currentPromise.then(func)
})
return Promise.all(promises)
}
function parallelLimit (funcs) {
let batches = funcs.reduce(function (last, next, index) {
if (index % limit == 0) last.push([next])
else last[last.length-1].push(next)
return last
}, [])
let currentPromise = Promise.resolve()
let promises = batches.map(function (batch) {
return currentPromise = currentPromise.then(function () {
return Promise.all(batch)
})
})
return Promise.all(promises)
.then(function (results) {
return Array.prototype.concat.apply([], results) // flatten array
})
}
function wilst (test, func) {
if (!test()) return Promise.resolve()
return func().then(function () {
return wilst(test, func)
})
}
function doWilst (func, test) {
return func().then(function () {
if (!test()) return Promise.resolve()
return doWilst(func, test)
})
}
function until (test, func) {
if (test()) return Promise.resolve()
return func().then(function () {
return wilst(test, func)
})
}
function doUntil (func, test) {
return func().then(function () {
if (test()) return Promise.resolve()
return doUntil(func, test)
})
}
function forever (func) {
return func().then(function () { return forever(func) })
}
@calmdev
Copy link

calmdev commented Nov 21, 2013

Thanks for posting this. I'm exploring moving from async to promises with Q right now and this is extremely helpful.

@twistedstream
Copy link

Excellent gist! I've already used it to build a few of my own libraries.

Quick question: any reason why your reduce and reduceRight functions are using Array.map instead of Array.forEach? I created a RSVP.js version of your reduce function using forEach and it seemed to work.

@wavded
Copy link
Author

wavded commented Aug 19, 2014

sheesh I wish github would notify me when someone comments on a gist :) I just got these comments! @twistedstream, i probably was in a map mode, seems forEach would work just as well :)

@christiansaiki
Copy link

Great gist! Thanks for sharing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment