Request Queue Implementation in JavaScript
This challenge asks you to implement a request queue in JavaScript. A request queue is a data structure that manages a series of requests, processing them one at a time to prevent overwhelming a system (like an API or database). This is crucial for building robust and scalable applications.
Problem Description
You are tasked with creating a RequestQueue class in JavaScript. This class should manage a queue of requests, allowing you to add requests and process them sequentially. Each request should be a function that returns a Promise. The queue should process requests one at a time, waiting for each Promise to resolve before moving on to the next. The queue should also handle errors gracefully, ensuring that unhandled rejections don't crash the application.
Key Requirements:
addRequest(request): Adds a request (a function returning a Promise) to the queue.processQueue(): Starts processing the requests in the queue. This method should return a Promise that resolves when all requests in the queue have completed successfully, or rejects if any request fails.- Error Handling: If a request's Promise rejects, the
processQueue()method should reject with the same error. - Sequential Processing: Requests must be processed one after another, waiting for each to complete before starting the next.
- Queue Management: The queue should internally manage the order of requests.
Expected Behavior:
- Adding requests to the queue should not immediately trigger processing.
processQueue()should initiate the processing of requests.- The
processQueue()method should return a Promise that reflects the overall success or failure of the queue processing. - The queue should handle empty queues gracefully.
Edge Cases to Consider:
- What happens if
addRequestis called multiple times beforeprocessQueueis called? - What happens if
processQueueis called multiple times? (Should it restart the queue or continue processing?) For this challenge, assume callingprocessQueuemultiple times should restart the queue. - How should errors be handled within the requests themselves?
- What happens if a request takes a very long time to complete?
Examples
Example 1:
Input:
queue.addRequest(() => Promise.resolve("Request 1"));
queue.addRequest(() => Promise.resolve("Request 2"));
queue.processQueue();
Output:
["Request 1", "Request 2"]
Explanation:
The queue processes the requests sequentially. "Request 1" resolves first, then "Request 2" resolves. The `processQueue()` method resolves with an array containing the results of each request.
Example 2:
Input:
queue.addRequest(() => Promise.resolve("Request 1"));
queue.addRequest(() => Promise.reject("Request 2 failed"));
queue.processQueue();
Output:
Error: "Request 2 failed"
Explanation:
The queue processes the requests sequentially. "Request 1" resolves. "Request 2" rejects with the error "Request 2 failed". The `processQueue()` method rejects with the same error.
Example 3: (Empty Queue)
Input:
queue.processQueue();
Output:
[]
Explanation:
The queue is empty. `processQueue()` resolves immediately with an empty array.
Constraints
- The requests added to the queue must be functions that return Promises.
- The maximum number of requests that can be added to the queue at any given time is 100.
- The
processQueue()method should complete within a reasonable timeframe (e.g., no more than 5 seconds for a queue of 10 requests, each taking approximately 0.5 seconds). While a strict time limit isn't enforced for grading, excessively slow code will be considered. - The
RequestQueueclass should be implemented using JavaScript's built-in Promise functionality.
Notes
- Consider using an array to store the requests in the queue.
- Think about how to manage the state of the queue (e.g., whether it's currently processing requests).
- Use
async/awaitfor cleaner asynchronous code. - Focus on clarity, readability, and error handling. A well-structured and documented solution is preferred.
- The order of requests added to the queue is important and must be preserved during processing.