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