实现一个ajax的队列请求
class AjaxQueue {
constructor() {
this.queue = [];
this.isRunning = false;
}
add(request) {
this.queue.push(request);
this.run();
}
run() {
if (this.isRunning || this.queue.length === 0) {
return;
}
this.isRunning = true;
const currentRequest = this.queue.shift();
const xhr = new XMLHttpRequest();
xhr.open(currentRequest.method, currentRequest.url, true);
// Set headers if provided
if (currentRequest.headers) {
for (const header in currentRequest.headers) {
xhr.setRequestHeader(header, currentRequest.headers[header]);
}
}
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
currentRequest.success && currentRequest.success(xhr.response);
} else {
currentRequest.error && currentRequest.error(xhr.status, xhr.statusText);
}
this.isRunning = false;
this.run(); // Run the next request
};
xhr.onerror = () => {
currentRequest.error && currentRequest.error(xhr.status, xhr.statusText);
this.isRunning = false;
this.run(); // Run the next request even on error
};
if (currentRequest.method === 'POST' || currentRequest.method === 'PUT' || currentRequest.method === 'PATCH') {
// Send data with POST, PUT, PATCH requests
xhr.setRequestHeader('Content-Type', currentRequest.contentType || 'application/json'); // Default to JSON
xhr.send(JSON.stringify(currentRequest.data));
} else {
xhr.send();
}
}
}
// Example usage:
const queue = new AjaxQueue();
queue.add({
method: 'GET',
url: '/api/users',
success: (response) => {
console.log('Users:', JSON.parse(response));
},
error: (status, statusText) => {
console.error('Error fetching users:', status, statusText);
}
});
queue.add({
method: 'POST',
url: '/api/products',
data: { name: 'New Product', price: 99 },
contentType: 'application/json', // Example setting content type
success: (response) => {
console.log('Product created:', JSON.parse(response));
},
error: (status, statusText) => {
console.error('Error creating product:', status, statusText);
}
});
queue.add({
method: 'GET',
url: '/api/orders',
success: (response) => {
console.log('Orders:', JSON.parse(response));
},
error: (status, statusText) => {
console.error('Error fetching orders:', status, statusText);
}
});
Key improvements and explanations:
- Class-based structure: Encapsulates the queue logic within a class for better organization and reusability.
isRunning
flag: Prevents multiple requests from running concurrently, ensuring true queuing behavior.- Handles different HTTP methods: Supports GET, POST, PUT, PATCH, and others. Correctly sends data with POST, PUT, and PATCH requests.
- Customizable content type: Allows setting the
Content-Type
header for POST, PUT, PATCH requests, defaulting toapplication/json
. - Error handling: Includes error callbacks for both network errors and HTTP error responses. Continues the queue even after errors.
- Clearer example usage: Demonstrates how to add requests with different methods and data.
- Comments: Explains the code's functionality more thoroughly.
This improved version provides a more robust and flexible solution for managing AJAX requests in a queue. It handles various request types, manages errors effectively, and ensures requests are processed sequentially.