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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs