JAVASCRIPT
Manage API Rate Limits with a Client-Side Request Queue
Implement a JavaScript request queue with a fixed delay to prevent hitting API rate limits, ensuring smooth and controlled data fetching from external services.
class ApiRequestQueue {
constructor(delayMs = 1000) {
this.queue = [];
this.delayMs = delayMs;
this.isProcessing = false;
}
addRequest(requestFn) {
return new Promise((resolve, reject) => {
this.queue.push({ requestFn, resolve, reject });
this.processQueue();
});
}
async processQueue() {
if (this.isProcessing || this.queue.length === 0) {
return;
}
this.isProcessing = true;
const { requestFn, resolve, reject } = this.queue.shift();
try {
const result = await requestFn();
resolve(result);
} catch (error) {
reject(error);
} finally {
// Wait for the delay before processing the next request
await new Promise(res => setTimeout(res, this.delayMs));
this.isProcessing = false;
this.processQueue(); // Process next request
}
}
}
// --- Usage Example ---
const apiQueue = new ApiRequestQueue(500); // 500ms delay between requests
async function fetchUser(userId) {
console.log(`Fetching user ${userId}...`);
// Simulate an API call
return new Promise(resolve => setTimeout(() => {
resolve({ id: userId, name: `User ${userId}` });
}, Math.random() * 300 + 100)); // Simulate variable API response time
}
async function fetchDataWithQueue() {
try {
const user1 = await apiQueue.addRequest(() => fetchUser(1));
console.log('User 1 data:', user1);
const user2 = await apiQueue.addRequest(() => fetchUser(2));
console.log('User 2 data:', user2);
// Even if called immediately, requests will be processed with a delay
const user3 = await apiQueue.addRequest(() => fetchUser(3));
console.log('User 3 data:', user3);
console.log('All users fetched via queue.');
} catch (error) {
console.error('Error fetching data:', error);
}
}
fetchDataWithQueue();
How it works: This JavaScript `ApiRequestQueue` class helps manage API requests to avoid hitting rate limits. It queues incoming API calls and processes them one by one, introducing a configurable delay between each request. This ensures a controlled flow of requests, preventing a burst of calls that might exceed an API's usage limits, and wraps each request in a Promise for easy async/await handling.