问题
I'm having an issue with using jQuery.when() to wait for multiple ajax requests to finish before calling another function.
Each ajax request will get JSON data, and looks something like this:
function loadData(arg){
var ajaxCall = $.ajax(
URL // depends on arg
)
.error( .... );
return ajaxCall;
}
When the request is called, the return value (ajaxCall) is added to a list called ajaxRequests.
ajaxRequests = [];
ajaxREquests.push(loadData(arg))
When all the requests have been made, I'm trying to pass ajaxRequests to $.when in order to wait for all requests to complete.
var defer = $.when.apply($, ajaxRequests);
defer.done(function(args){
for (var i=0; i<args.length; i++){
inst.loadData($.parseJSON(args[i].responseText));
}
inst.draw();
});
inst is an object that loads and draws graphs based on JSON data.
The problem is that it doesn't seem to be actually waiting for the requests to finish - args[i] is an object, but responseText is undefined when the code runs. If I save args[i] and access it later from the console, it works.
I suspect the problem is related to using .when with an arbitrary number of arguments, as all the examples I've seen on the web give it a pre-defined argument list.
I'm not sure if using apply was the right idea or not, but either way it doesn't work properly and behaves erratically (browser-dependent).
Any help would be greatly appreciated.
Please let me know if more information is required.
I'm using jQuery 1.5
回答1:
Although Alex did indeed provide a solution to his problem, I found following it a bit difficult. I had an issue similar to his that I solved, and I wanted to share my solution for anyone else who needs to process a variable number of ajax requests.
// Array of requests
var requests = Array();
requests.push($.get('responsePage.php?data=foo'));
requests.push($.get('responsePage.php?data=bar'));
var defer = $.when.apply($, requests);
defer.done(function(){
// This is executed only after every ajax request has been completed
$.each(arguments, function(index, responseData){
// "responseData" will contain an array of response information for each specific request
});
});
回答2:
In addition to Andy Corman's answer (I am yet unable to reply to a post, I think ...), if you only have one request, the response information will be passed directly to the defer.done - function as an argument; So you need to provide an if for that case:
// Array of requests
var requests = Array();
requests.push($.get('responsePage.php?data=foo'));
var defer = $.when.apply($, requests);
defer.done(function(){
// This is executed only after every ajax request has been completed
if (requests.length == 1)
// "arguments" will be the array of response information for the request
else
$.each(arguments, function(index, responseData){
// "responseData" will contain an array of response information for each specific request
});
});
回答3:
I think I've worked it out now - the problem was in processing the returned arguments. .done was getting passed three arguments only - the response text, status and jqXHR object. I was expecting it to get passed the jqXHR object resulting from each query.
I've solved it by moving the callback code for each query to a separate function (i.e. the ajax call in loadData is now specifying a callback function which does the '.loadData(...)' call) and the only thing being done by the .done call is the inst.draw(). This seems to work fine: the individual callback's are each execute before .done().
I'm not sure if that's exactly how it's supposed to work, but it seems to be doing the job.
回答4:
Try ajaxStart and ajaxStop, which have listeners for open ajax requests.
http://api.jquery.com/ajaxStart/ http://api.jquery.com/ajaxStop/
来源:https://stackoverflow.com/questions/9865586/jquery-when-troubleshooting-with-variable-number-of-arguments