JAVASCRIPT
Manage API Request Rates with a Simple Delay Queue (JavaScript)
Implement a basic client-side request queue with a configurable delay to prevent exceeding API rate limits and ensure smooth, controlled data fetching.
/**
* A simple rate-limiting queue for API requests.
* Processes requests sequentially with a minimum delay between each.
*/
class RateLimiterQueue {
constructor(delayMs = 1000) {
this.queue = [];
this.delayMs = delayMs;
this.isProcessing = false;
}
/**
* Adds an API request function to the queue.
* The function should return a Promise.
*
* @param {Function} requestFn A function that executes an API call and returns a Promise.
* @returns {Promise<any>} A promise that resolves with the result of the API call.
*/
enqueue(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 specified delay before processing the next item
await new Promise(res => setTimeout(res, this.delayMs));
this.isProcessing = false;
// Recursively call processQueue to handle the next item if any
this.processQueue();
}
}
}
// --- Example Usage ---
const apiLimiter = new RateLimiterQueue(500); // 500ms delay between requests
async function fetchUserData(userId) {
// Simulate an API call
console.log(`[${new Date().toLocaleTimeString()}] Fetching user ${userId}...`);
return new Promise(resolve => {
setTimeout(() => {
console.log(`[${new Date().toLocaleTimeString()}] Fetched user ${userId}.`);
resolve({ id: userId, name: `User ${userId}`, data: Math.random() });
}, Math.random() * 500 + 200); // Simulate variable API response time
});
}
// Enqueue multiple requests
apiLimiter.enqueue(() => fetchUserData(1))
.then(data => console.log('Result 1:', data))
.catch(error => console.error('Error 1:', error));
apiLimiter.enqueue(() => fetchUserData(2))
.then(data => console.log('Result 2:', data))
.catch(error => console.error('Error 2:', error));
apiLimiter.enqueue(() => fetchUserData(3))
.then(data => console.log('Result 3:', data))
.catch(error => console.error('Error 3:', error));
// You can add more requests dynamically
setTimeout(() => {
apiLimiter.enqueue(() => fetchUserData(4))
.then(data => console.log('Result 4:', data))
.catch(error => console.error('Error 4:', error));
}, 1500);
How it works: This JavaScript snippet provides a `RateLimiterQueue` class to manage the frequency of API requests. It enqueues API call functions and processes them sequentially, introducing a configurable delay between each request. This client-side strategy helps prevent applications from inadvertently exceeding API rate limits, ensuring a smoother interaction with external services and avoiding temporary bans.