Mastering Asynchronous Task Management in TypeScript with q-exec-ts
Source: Dev.to
Handling a massive influx of asynchronous tasks in Node.js can be challenging. Whether you are processing a large batch of API requests, dealing with data streams, or managing database operations, unbridged concurrency can quickly overwhelm your system or trigger third‑party rate limits. This is where q‑exec‑ts, a TypeScript library created by @arpad1337, comes into play to elegantly solve this problem.
Overview
q-exec-ts is a focused, lightweight TypeScript utility built around a QueuedExecutor class that enables developers to smoothly control task concurrency and throttle script executions. Under the hood, it extends the native Node.js events.EventEmitter class, providing an event‑driven approach to tracking tasks in a queue.
Features
- Strict Typing – Uses a custom
PositiveIntegertype constraint to enforce positive integer values for max concurrency and delay. - Delegate Pattern – Configure a
QueuedExecutorDelegateobject once instead of passing callbacks for every queued item. The delegate requires a singleexecmethod that processes the typed arguments. - Built‑in Throttling – The constructor accepts a
delay(ms) that acts as a throttle, using timeouts to ensure subsequent tasks are not started before the delay window has elapsed. - Event‑Driven Lifecycle – Emits useful events:
bufferEmptywhen the internal buffer runs dry.finishedwhen the input stream is explicitly closed and all pending executions have completed.
Usage
Defining the Delegate
import * as events from "events";
import {
QueuedExecutor,
QueuedExecutorDelegate,
QueuedExecutorEvents
} from "./QueuedExecutor";
type ArgsType = [string];
const delegate: QueuedExecutorDelegate = {
exec: async (...args: ArgsType): Promise => {
try {
// Your async logic here
await doSomethingAsync(args[0]);
} catch (e) {
console.error(e);
}
}
};
Instantiating the Executor
const maxConcurrency = 5; // example value
const executor = new QueuedExecutor(
maxConcurrency,
100, // throttling delay in ms
delegate
);
Pushing Tasks
executor.push(someString);
The queue stores the parameters in a buffer and automatically runs them as slots become available based on the concurrency threshold.
Closing the Input Stream
executor.inputStreamClosed(); // Signals no more items will be pushed
await events.once(executor, QueuedExecutorEvents.Finished);
When the source data stream is complete, notifying the executor allows it to gracefully wind down and emit the terminal Finished event.
License
q-exec-ts is open‑source and released under the permissive MIT License by Arpad K. (copyright 2025). It is safe to embed within personal, commercial, or enterprise‑scale projects.
Repository: