diff options
Diffstat (limited to 'ext/js/general/task-accumulator.js')
-rw-r--r-- | ext/js/general/task-accumulator.js | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/ext/js/general/task-accumulator.js b/ext/js/general/task-accumulator.js index cae58b94..cb136908 100644 --- a/ext/js/general/task-accumulator.js +++ b/ext/js/general/task-accumulator.js @@ -18,25 +18,46 @@ import {log} from '../core.js'; +/** + * @template K,V + */ export class TaskAccumulator { + /** + * @param {(tasks: [key: ?K, task: import('task-accumulator').Task<V>][]) => Promise<void>} runTasks + */ constructor(runTasks) { + /** @type {?Promise<void>} */ this._deferPromise = null; + /** @type {?Promise<void>} */ this._activePromise = null; + /** @type {import('task-accumulator').Task<V>[]} */ this._tasks = []; + /** @type {import('task-accumulator').Task<V>[]} */ this._tasksActive = []; + /** @type {Map<K, import('task-accumulator').Task<V>>} */ this._uniqueTasks = new Map(); + /** @type {Map<K, import('task-accumulator').Task<V>>} */ this._uniqueTasksActive = new Map(); + /** @type {() => Promise<void>} */ this._runTasksBind = this._runTasks.bind(this); + /** @type {() => void} */ this._tasksCompleteBind = this._tasksComplete.bind(this); - this._runTasks = runTasks; + /** @type {(tasks: [key: ?K, task: import('task-accumulator').Task<V>][]) => Promise<void>} */ + this._runTasksCallback = runTasks; } + /** + * @param {?K} key + * @param {V} data + * @returns {Promise<void>} + */ enqueue(key, data) { if (this._deferPromise === null) { const promise = this._activePromise !== null ? this._activePromise : Promise.resolve(); this._deferPromise = promise.then(this._runTasksBind); } + /** @type {import('task-accumulator').Task<V>} */ const task = {data, stale: false}; if (key !== null) { const activeTaskInfo = this._uniqueTasksActive.get(key); @@ -52,6 +73,9 @@ export class TaskAccumulator { return this._deferPromise; } + /** + * @returns {Promise<void>} + */ _runTasks() { this._deferPromise = null; @@ -64,18 +88,28 @@ export class TaskAccumulator { return this._activePromise; } + /** + * @returns {Promise<void>} + */ async _runTasksAsync() { try { - const allTasks = [ - ...this._tasksActive.map((taskInfo) => [null, taskInfo]), - ...this._uniqueTasksActive.entries() - ]; - await this._runTasks(allTasks); + /** @type {[key: ?K, task: import('task-accumulator').Task<V>][]} */ + const allTasks = []; + for (const taskInfo of this._tasksActive) { + allTasks.push([null, taskInfo]); + } + for (const [key, taskInfo] of this._uniqueTasksActive) { + allTasks.push([key, taskInfo]); + } + await this._runTasksCallback(allTasks); } catch (e) { log.error(e); } } + /** + * @returns {void} + */ _tasksComplete() { this._tasksActive.length = 0; this._uniqueTasksActive.clear(); |