DockerERTFF/lib/core/async.js

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));
},
};