@stackbit/utils
Version:
Stackbit utilities
65 lines • 2.37 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Worker = void 0;
const lodash_1 = __importDefault(require("lodash"));
const promise_utils_1 = require("./promise-utils");
class Worker {
constructor() {
this.promise = Promise.resolve();
this.enqueued = [];
}
schedule(jobFn) {
return new Promise((resolve, reject) => {
this.promise = this.promise.finally(() => {
const res = jobFn();
if (res && typeof lodash_1.default.get(res, 'then') === 'function') {
return res.then(resolve).catch(reject);
}
else {
resolve(res);
}
});
});
}
/**
* Run one after another 2 calls of same jobFn, 3rd and next calls will be waiting for finishing 2nd and
* respond all together
* In case there are another jobFn called on the same worker - 2nd round of calls would be postponed to process next call
* to prevent dead lock
* @see https://user-images.githubusercontent.com/97896/90123842-1fea2f80-dd68-11ea-8462-d4f1cdc1749b.png
* @param {String} jobId
* @param {Function} jobFn
* @returns {Promise}
*/
enqueueOnce(jobId, jobFn) {
let enqueued = this.enqueued.find((obj) => obj.jobId === jobId);
if (enqueued) {
if (!enqueued.nextJobFn) {
enqueued.nextJobFn = jobFn;
}
return enqueued.deferred.promise;
}
enqueued = {
jobId,
jobFn,
deferred: (0, promise_utils_1.deferredPromise)(),
nextJobFn: null
};
this.enqueued.push(enqueued);
return this.schedule(jobFn).finally(() => {
if (!enqueued) {
return;
}
const index = this.enqueued.indexOf(enqueued);
this.enqueued.splice(index, 1);
if (enqueued.nextJobFn) {
this.enqueueOnce(enqueued.jobId, enqueued.nextJobFn).then(enqueued.deferred.resolve).catch(enqueued.deferred.reject);
}
});
}
}
exports.Worker = Worker;
//# sourceMappingURL=worker.js.map
;