I wrote a helper to limit Q promise concurrency.
If I have a promise-returning function promiseSomething
, writing
promiseSomething = PromiseScheduler.limitConcurrency(promiseSomething, 5);
ensures no more than 5 promises are pending at the same time.
I'm coming to JS from .NET world, and I welcome critique of this code.
It seems to work fine, but I wonder if it can be made shorter / more concise / plain better.
One of the thing worth remembering is that Q always schedules continuations on the next tick.
'use strict';
var q = require('q');
/**
* Constructs a function that proxies to promiseFactory
* limiting the count of promises that can run simultaneously.
* @param promiseFactory function that returns promises.
* @param limit how many promises are allowed to be running at the same time.
* @returns function that returns a promise that eventually proxies to promiseFactory.
*/
function limitConcurrency(promiseFactory, limit) {
var running = 0,
semaphore;
function scheduleNextJob() {
if (running < limit) {
running++;
return q();
}
if (!semaphore) {
semaphore = q.defer();
}
return semaphore.promise
.finally(scheduleNextJob);
}
function processScheduledJobs() {
running--;
if (semaphore && running < limit) {
semaphore.resolve();
semaphore = null;
}
}
return function () {
var _this = this,
args = arguments;
function runJob() {
return promiseFactory.apply(_this, args);
}
return scheduleNextJob()
.then(runJob)
.finally(processScheduledJobs);
};
}
module.exports = {
limitConcurrency: limitConcurrency
};