@ai-zen/async-queue
Version:
AsyncQueue is a TypeScript class that provides a simple asynchronous queue implementation. It implements the `Symbol.asyncIterator` interface, allowing it to be used in `for-await-of` loops. This enables one or multiple consumers to process items in the q
155 lines (109 loc) • 3.57 kB
Markdown
# AsyncQueue
AsyncQueue is a TypeScript class that provides a simple asynchronous queue implementation. It implements the `Symbol.asyncIterator` interface, allowing it to be used in `for-await-of` loops. This enables one or multiple consumers to process items in the queue asynchronously.
## Installation
Install AsyncQueue using npm:
```
npm install @ai-zen/async-queue
```
## Usage
### Importing
```typescript
import AsyncQueue from "@ai-zen/async-queue";
```
### Creating an AsyncQueue Instance
```typescript
const queue = new AsyncQueue([1, 2, 3]);
```
### Pushing Values to the Queue
```typescript
queue.push(value);
// Or
queue.push(value1, value2, value3, ...);
// Or
queue.push(...values);
```
The `push` method adds one or more values to the queue, and increases its size.
### Marking the Queue as Done
```typescript
queue.done();
```
The `done` method marks the queue as finished. This indicates that no more items will be added to the queue.
### Iterating Over the Queue
```typescript
for await (const value of queue) {
// Consume the value
}
```
The `for await...of` loop can be used to iterate over the items in the queue. This loop is asynchronous and will wait for each value to be available before consuming it.
### Getting the Size of the Queue
```typescript
const size = queue.size;
```
The `size` property returns the current size of the queue.
## Examples
### Example 1: Single Consumer
You can add data asynchronously while consuming data asynchronously.
```typescript
const queue = new AsyncQueue();
(async () => {
for (const value of [1, 2, 3, 4, 5]) {
await sleep(1); // Simulate asynchronous operations
queue.push(value);
}
queue.done();
})();
for await (const value of queue) {
await sleep(1); // Simulate asynchronous operations
console.log(value);
}
console.log("Done!");
```
Output:
```
1
2
3
4
5
Done!
```
### Example 2: Multiple Consumers
This is useful for limiting the number of concurrent operations, such as network requests.
```typescript
// Assume `Task` and `TaskResult` are types defined elsewhere in your code
const queue = new AsyncQueue<Task>(tasks);
queue.done();
const results: TaskResult[] = [];
// Start 10 concurrent consumers using the competing-consumers pattern
await Promise.all(
Array.from({ length: 10 }).map(async () => {
for await (const task of queue) {
try {
const result = await download(task); // Perform the task
results.push(result);
} catch (error) {
console.error("Task failed:", error);
}
}
})
);
```
### Example 3: Backpressure
The library provides a very simple backpressure control mechanism that can prevent the queue length from exceeding a threshold. Just call and wait for the `backpressure` method before `push`. If the queue reaches the threshold, the `backpressure` method will wait until the queue length decreases to have space.
```typescript
const queue = new AsyncQueue<number>();
const result: number[] = [];
(async () => {
for (const value of Array.from({ length: 100 }).map((_, i) => i)) {
await queue.backpressure(10); // Wait for the queue to have space, the maximum size is 10
queue.push(value);
}
queue.done();
})();
for await (const value of queue) {
await sleep(1000); // Simulate asynchronous operations
result.push(value);
}
```
## License
This package is licensed under the MIT License.