dashboard/utils/promise.js

96 lines
2.0 KiB
JavaScript

import Queue from './queue';
async function _hash(hash, fnName) {
const keys = Object.keys(hash);
const promises = Object.values(hash);
const res = await Promise[fnName](promises);
const out = {};
for ( let i = 0 ; i < keys.length ; i++ ) {
out[keys[i]] = res[i];
}
return out;
}
export function allHash(hash) {
return _hash(hash, 'all');
}
export function allHashSettled(hash) {
return _hash(hash, 'allSettled');
}
export function eachLimit(items, limit, iterator, debug = false) {
if (debug) {
console.log('eachLimit of', items.length, ' items', limit, 'at a time'); // eslint-disable-line no-console
}
return new Promise((resolve, reject) => {
const queue = new Queue();
let pending = 0;
let failed = false;
const out = [];
for (let i = 0; i < items.length; i++) {
queue.enqueue({ item: items[i], idx: i });
}
process();
function process() {
if (debug) {
console.log(`process, queue=${ queue.getLength() }, pending=${ pending }, failed=${ failed }`); // eslint-disable-line no-console
}
if (failed) {
return;
}
if (queue.isEmpty() && pending === 0) {
return resolve(out);
}
while (!queue.isEmpty() && pending < limit && !failed) {
const { item, idx } = queue.dequeue();
if (debug) {
console.log('Running', item); // eslint-disable-line no-console
}
pending++;
iterator(item, idx).then((res) => {
if (debug) {
console.log('Done', item); // eslint-disable-line no-console
}
out[idx] = res;
pending--;
process();
}).catch((err) => {
if (debug) {
console.log('Failed', err, item); // eslint-disable-line no-console
}
failed = true;
reject(err);
});
}
}
});
}
export function deferred(name) {
const out = {};
out.promise = new Promise((resolve, reject) => {
out.resolve = resolve;
out.reject = reject;
}, name);
return out;
}