palinode
Version:
node callback-based flow control utility library
58 lines (41 loc) • 1.76 kB
JavaScript
;
module.exports = {
throttledConcurrentAll(functionsToRun, numWorkers, callback) {
if(typeof (numWorkers) === 'function') {
callback = numWorkers;
numWorkers = Math.floor(functionsToRun.length / 2);
}
if(functionsToRun.length === 0) { return callback(null, []); }
const actualNumWorkers = functionsToRun.length < numWorkers ? functionsToRun.length : numWorkers;
const concurrentWorker = (state, done) => {
if(state.numComplete === state.functionsToRun.length) { return; }
if(state.indexToProcess >= state.functionsToRun.length) { return; }
const indexToProcess = state.indexToProcess;
const toDo = state.functionsToRun[indexToProcess];
const resultPosition = indexToProcess;
++state.indexToProcess;
toDo(function(error, result) {
if(error) ++state.numErrors;
state.results[resultPosition] = {
error: error || null,
result: error ? null : result
};
++state.numComplete;
if(state.numComplete === state.functionsToRun.length) {
return done(state.numErrors || null, state.results);
}
process.nextTick(() => concurrentWorker(state, done));
});
};
const initialState = {
functionsToRun: functionsToRun,
results: [],
indexToProcess: 0,
numComplete: 0,
numErrors: 0
};
for (let x = 0; x < actualNumWorkers; ++x) {
process.nextTick(() => concurrentWorker(initialState, callback));
}
}
};