class RequestThrottler {
constructor(maxRequestsPerSecond) {
this.maxRequestsPerSecond = maxRequestsPerSecond;
this.requestQueue = [];
this.lastRequestTime = 0;
}
/**
* Throttles a request to prevent overwhelming the system.
* @param {function} requestFunction The function to execute (the actual request).
* @param {object} data The data to send with the request.
* @returns {Promise} A promise that resolves when the request is complete.
* @throws {Error} If the data is invalid.
*/
throttle(requestFunction, data) {
// Input validation
if (!data || typeof data !== 'object') {
throw new Error("Invalid data: Data must be an object.");
}
if (typeof requestFunction !== 'function') {
throw new Error("Invalid requestFunction: requestFunction must be a function.");
}
return new Promise((resolve, reject) => {
const now = Date.now();
const timeSinceLastRequest = now - this.lastRequestTime;
if (timeSinceLastRequest < 1000 / this.maxRequestsPerSecond) {
// Queue the request if it's too frequent.
this.requestQueue.push({ function: requestFunction, data: data });
} else {
// Execute the request immediately.
this.lastRequestTime = now;
requestFunction(data, resolve, reject); // Pass resolve and reject to the function.
}
});
}
/**
* Processes the request queue.
*/
processQueue() {
while (this.requestQueue.length > 0) {
const { function: requestFunction, data: data } = this.requestQueue.shift();
this.throttle(requestFunction, data)
.then(() => {
// Request completed successfully.
})
.catch(error => {
// Request failed.
console.error("Request failed:", error);
// Optionally, handle the error (e.g., retry, log).
});
}
}
}
// Example usage:
// const throttler = new RequestThrottler(5); // Allow 5 requests per second
// async function fetchData(data, resolve, reject) {
// console.log("Fetching data:", data);
// await new Promise(resolve => setTimeout(resolve, 200)); // Simulate network request
// resolve({ message: "Data fetched successfully" });
// }
// try {
// await throttler.throttle(fetchData, { userId: 123 });
// console.log("Request completed.");
// } catch (error) {
// console.error("Error:", error);
// }
Add your comment