97 lines
2.2 KiB
JavaScript
97 lines
2.2 KiB
JavaScript
function defered() {
|
|
let resolve, reject;
|
|
let promise = new Promise((_resolve, _reject) => {
|
|
resolve = _resolve;
|
|
reject = _reject;
|
|
});
|
|
|
|
return {
|
|
promise,
|
|
resolve,
|
|
reject
|
|
};
|
|
}
|
|
|
|
function limit(concurrency) {
|
|
let running = 0;
|
|
let queue = [];
|
|
|
|
function init() {
|
|
if (running < concurrency) {
|
|
running++;
|
|
return Promise.resolve();
|
|
}
|
|
|
|
let defer = defered();
|
|
queue.push(defer);
|
|
return defer.promise;
|
|
}
|
|
|
|
function complete(a) {
|
|
let next = queue.shift();
|
|
|
|
if (next) {
|
|
next.resolve();
|
|
} else {
|
|
running--;
|
|
}
|
|
|
|
return a;
|
|
}
|
|
|
|
return function(fn) {
|
|
return function() {
|
|
let args = Array.prototype.slice.apply(arguments);
|
|
|
|
return init().then(() => {
|
|
return fn.apply(null, args);
|
|
}).finally(complete);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
map: function(arr, fn, concurrency) {
|
|
arr = Array.isArray(arr) ? arr : [arr];
|
|
|
|
if (concurrency) {
|
|
const limiter = limit(concurrency)
|
|
return Promise.all(arr.map(limiter(fn)));
|
|
}
|
|
|
|
return Promise.all(arr.map(fn));
|
|
},
|
|
|
|
mapSeries: function(arr, fn) {
|
|
arr = Array.isArray(arr) ? arr : [arr];
|
|
|
|
return arr.reduce((promise, curr, index, arr) => {
|
|
return promise.then(prev => {
|
|
return fn(curr, index, arr).then(val => {
|
|
prev.push(val);
|
|
return prev;
|
|
});
|
|
})
|
|
}, Promise.resolve([]));
|
|
},
|
|
|
|
reduce: function(arr, fn, start) {
|
|
arr = Array.isArray(arr) ? arr : [arr];
|
|
|
|
if (!arr.length) {
|
|
return Promise.resolve(start);
|
|
}
|
|
|
|
return arr.reduce((promise, curr, index, arr) => {
|
|
return promise.then(prev => {
|
|
if (prev === undefined && arr.length === 1) {
|
|
return curr;
|
|
}
|
|
|
|
return fn(prev, curr, index, arr);
|
|
});
|
|
}, Promise.resolve(start));
|
|
},
|
|
|
|
}; |