JAVASCRIPT
Client-Side Rate Limiting API Requests
Implement a client-side rate limiter using a queue to control the frequency of API requests, preventing exceeding external service limits and ensuring fair usage.
class RateLimiter {
constructor(requestsPerSecond) {
this.interval = 1000 / requestsPerSecond; // Milliseconds per request
this.queue = [];
this.lastExecutionTime = 0;
this.isProcessing = false;
}
async enqueue(requestFunction) {
return new Promise((resolve, reject) => {
this.queue.push({ requestFunction, resolve, reject });
if (!this.isProcessing) {
this.processQueue();
}
});
}
async processQueue() {
this.isProcessing = true;
while (this.queue.length > 0) {
const now = Date.now();
const timeSinceLastExecution = now - this.lastExecutionTime;
const timeToWait = this.interval - timeSinceLastExecution;
if (timeToWait > 0) {
await new Promise(res => setTimeout(res, timeToWait));
}
const { requestFunction, resolve, reject } = this.queue.shift();
this.lastExecutionTime = Date.now();
try {
const result = await requestFunction();
resolve(result);
} catch (error) {
reject(error);
}
}
this.isProcessing = false;
}
}
// Usage example:
// const apiLimiter = new RateLimiter(2); // Max 2 requests per second
// // Simulate multiple API calls
// for (let i = 0; i < 10; i++) {
// apiLimiter.enqueue(async () => {
// console.log(`Making API call ${i}... at ${Date.now()}`);
// const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${i + 1}`);
// if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
// return response.json();
// })
// .then(data => console.log(`Call ${i} success:`, data.id))
// .catch(error => console.error(`Call ${i} error:`, error.message));
// }
How it works: This JavaScript snippet provides a client-side rate limiter for API requests, designed to prevent applications from exceeding an external API's rate limits. It uses a queue-based approach where request functions are enqueued and then executed sequentially, ensuring a minimum delay between each call. The `RateLimiter` class manages the execution flow, calculating the necessary wait time based on the desired `requestsPerSecond` to maintain compliance with API usage policies without blocking the main thread.