jQuery Deferred返回过早问题:多查询异步场景代码求助
multipleQueries Alright, let's break down why your jQuery Deferred might be firing its then callback prematurely—even with the partial code you shared, there are a few key culprits to check:
You’re manually resolving
allQueriesMappedtoo early
If somewhere in your truncated code you’re callingallQueriesMapped.resolve()orallQueriesMapped.resolveWith()before all your asynchronous queries complete, that’s an instant trigger for thethencallback. Double-check that this resolve call is only executed after every query has finished.Misusing
$.when.apply()(the most likely culprit)
Your code cuts off at$.when.app..., which suggests you’re trying to wait for multiple deferreds using$.when.apply($, arrayOfDeferreds). This pattern fails and resolves early if:- You’re not correctly collecting valid Deferred/Promise objects from each query into an array to pass to
apply(). If the array is empty, or contains non-deferred values (like plain strings/objects),$.whenwill resolve immediately. - You’re passing the wrong context or parameters to
apply(), causing it to not wait for the async operations to finish.
- You’re not correctly collecting valid Deferred/Promise objects from each query into an array to pass to
Individual queries aren’t returning proper Deferreds
If the functions inqueriesToExecutedon’t return a valid jQuery Deferred/Promise (e.g., they run synchronously, or resolve their own deferreds immediately), then$.whenwill treat them as already completed and move on early.Missing error handling causing silent resolution
While less common, if one of your queries rejects its deferred but you haven’t set up a failure handler, jQuery might sometimes resolve the parent deferred unexpectedly instead of propagating the error.
Quick Fix for Your Code
Instead of manually managing a $.Deferred() instance, let $.when.apply() do the heavy lifting for you—it returns a new promise that resolves only when all child promises complete. Here’s how to refactor your function properly:
function multipleQueries(queriesToExecute, rowData) { // Convert single query to array if needed if (!Array.isArray(queriesToExecute)) { queriesToExecute = [queriesToExecute]; } // Map each query to its returned Deferred/Promise const queryPromises = queriesToExecute.map(query => { // Replace this with your actual query logic—make sure it returns a Deferred! // Example for an AJAX query: return $.ajax({ url: query.endpoint, data: rowData, method: query.method || "GET" }); }); // Return the combined promise from all queries return $.when.apply($, queryPromises); }
This eliminates the risk of manually resolving a deferred early, since $.when.apply() handles waiting for all async operations automatically.
内容的提问来源于stack exchange,提问作者Ctrl_Alt_Defeat

