如何在jQuery Deferred对象中结合定时器实现循环AJAX请求?
Hey there! Since you’re already comfortable with jQuery Deferreds, let’s break down how to implement this polling-asynchronous logic correctly. The key here is ensuring each polling function returns a properly managed Deferred that resolves only when its target counter hits zero, while also cleaning up the interval to avoid memory leaks.
Step 1: Refactor your polling functions to return a Deferred
Each function like getQueueCount() needs to create a Deferred, start the interval, and resolve/reject the Deferred once the condition is met (or an error occurs). Here’s a concrete implementation:
function getQueueCount() { // Create a new Deferred for this polling process const deferred = $.Deferred(); // Store the interval ID so we can clear it later const pollInterval = setInterval(() => { $.ajax({ url: '/your-api-endpoint', method: 'GET', success: (response) => { const currentCount = response.queueCount; console.log(`Queue count update: ${currentCount}`); // If counter hits zero, clean up and resolve the Deferred if (currentCount === 0) { clearInterval(pollInterval); deferred.resolve(`Queue cleared! Final count: ${currentCount}`); } }, error: (xhr, status, err) => { // On AJAX failure, clean up and reject the Deferred clearInterval(pollInterval); console.error('Polling failed:', err); deferred.reject(`Failed to fetch queue count: ${err}`); } }); }, 5000); // Poll every 5 seconds // Optional: Add a way to manually abort the polling if needed deferred.abort = () => { clearInterval(pollInterval); deferred.reject('Polling was manually aborted'); }; // Return the promise (not the raw Deferred) to prevent external manipulation return deferred.promise(); }
Step 2: Collect Deferreds and wait for all to complete
Once you’ve added all your polling functions to the deferreds array, use $.when.apply($, deferreds) to wait for every polling process to finish (either resolve or reject). This works because $.when doesn’t accept an array directly, so apply spreads the array into individual arguments.
// Build your array of Deferred promises const deferreds = []; deferreds.push(getQueueCount()); // Add more polling functions if needed: // deferreds.push(getAnotherQueueCount()); // deferreds.push(getThirdQueueCount()); // Wait for all polling processes to resolve or any to reject $.when.apply($, deferreds) .done((...results) => { // This runs ONLY when ALL Deferreds resolve successfully console.log('All queues are cleared!', results); // Execute your post-completion logic here }) .fail((error) => { // This runs if ANY Deferred is rejected (AJAX error, abort, etc.) console.error('One or more polling tasks failed:', error); // Handle error cases here });
Key Things to Remember
- Always clean up intervals: If you forget to call
clearIntervalafter resolving/rejecting, the interval will keep running indefinitely, wasting resources. - Return promises, not raw Deferreds: Using
deferred.promise()prevents external code from accidentally resolving/rejecting the Deferred early. - Handle errors: Don’t ignore AJAX failures—reject the Deferred and clean up the interval immediately to avoid stuck polling.
- Manual abort (optional): Adding an
abortmethod gives you control to stop polling early if needed (e.g., user navigates away).
内容的提问来源于stack exchange,提问作者AdRock

