Promise.filter = function (iterable, filterer, options = {}) { let concurrency = options.concurrency || Infinity let index = 0 const results = [] const predicates = [] const pending = [] const iterator = iterable[Symbol.iterator]() while (concurrency-- > 0) { const pending = wrappedFilterer() if (pending) pending.push(promise) else break } return Promise.all(pending).then(() => results.filter((v, i) => predicates[i])) function wrappedFilterer () { const next = iterator.next() if (next.done) return null const i = index++ results.push(next.value) const predicate = filterer(next.value, i) return Promise.resolve(predicate).then(resolved => { predicates[i] = resolved return wrappedFilterer() }) } }