JAVASCRIPT
Implement a Sequential API Request Queue in JavaScript
Manage a series of API calls that need to be executed sequentially or with controlled concurrency, preventing race conditions and ensuring orderly processing of requests.
class ApiRequestQueue {
constructor() {
this.queue = [];
this.isProcessing = false;
}
/**
* Adds a request function to the queue.
* The request function should return a Promise.
* @param {Function} requestFn - A function that returns a Promise for an API call.
* @returns {Promise} - A promise that resolves with the result of the request function.
*/
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 {
this.isProcessing = false;
// Process the next item in the queue
this.processQueue();
}
}
}
// Example Usage:
const requestQueue = new ApiRequestQueue();
// Simulate API calls
const makeApiCall = (id, delay) => {
return () => new Promise(resolve => {
setTimeout(() => {
console.log(`API Call ${id} completed after ${delay}ms`);
resolve(`Result from API Call ${id}`);
}, delay);
});
};
// Add requests to the queue
console.log('All requests added to queue. Processing sequentially...');
requestQueue.addRequest(makeApiCall(1, 1000))
.then(result => console.log('Handler for Call 1:', result))
.catch(error => console.error('Error for Call 1:', error));
requestQueue.addRequest(makeApiCall(2, 500)) // This will wait for call 1
.then(result => console.log('Handler for Call 2:', result))
.catch(error => console.error('Error for Call 2:', error));
requestQueue.addRequest(makeApiCall(3, 1500)) // This will wait for call 2
.then(result => console.log('Handler for Call 3:', result))
.catch(error => console.error('Error for Call 3:', error));
How it works: This JavaScript snippet implements a simple `ApiRequestQueue` class that ensures API calls are executed sequentially. This pattern is invaluable when dealing with APIs that require requests in a specific order, have strict rate limits, or when you need to prevent race conditions that could lead to inconsistent data. Requests are added to an internal queue, and the `processQueue` method asynchronously executes them one by one. Each request is a function that returns a Promise, allowing the queue to await its completion before moving to the next, guaranteeing ordered execution.