tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

AsyncQueue.sys.mjs (1866B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /**
      6 * Manages a queue of asynchronous tasks, ensuring they are processed sequentially.
      7 */
      8 export class AsyncQueue {
      9  #processing;
     10  #queue;
     11 
     12  constructor() {
     13    this.#queue = [];
     14    this.#processing = false;
     15  }
     16 
     17  /**
     18   * Dequeue a task.
     19   *
     20   * @returns {Promise}
     21   *     The wrapped task appearing as first item in the queue.
     22   */
     23  #dequeue() {
     24    return this.#queue.shift();
     25  }
     26 
     27  /**
     28   * Dequeue and try to process all the queued tasks.
     29   *
     30   * @returns {Promise<undefined>}
     31   *     Promise that resolves when processing the queue is done.
     32   */
     33  async #processQueue() {
     34    // The queue is already processed or no tasks queued up.
     35    if (this.#processing || this.#queue.length === 0) {
     36      return;
     37    }
     38 
     39    this.#processing = true;
     40 
     41    while (this.#queue.length) {
     42      const wrappedTask = this.#dequeue();
     43      await wrappedTask();
     44    }
     45 
     46    this.#processing = false;
     47  }
     48 
     49  /**
     50   * Enqueue a task.
     51   *
     52   * @param {Function} task
     53   *     The task to queue.
     54   *
     55   * @returns {Promise<object>}
     56   *     Promise that resolves when the task is completed, with the resolved
     57   *     value being the result of the task.
     58   */
     59  enqueue(task) {
     60    const onTaskExecuted = new Promise((resolve, reject) => {
     61      // Wrap the task in a function that will resolve or reject the Promise.
     62      const wrappedTask = async () => {
     63        try {
     64          const result = await task();
     65          resolve(result);
     66        } catch (error) {
     67          reject(error);
     68        }
     69      };
     70 
     71      // Add the wrapped task to the queue
     72      this.#queue.push(wrappedTask);
     73      this.#processQueue();
     74    });
     75 
     76    return onTaskExecuted;
     77  }
     78 }