在使用可变数量的参数进行故障排除时。

时间:2022-08-23 11:07:36

I'm having an issue with using jQuery.when() to wait for multiple ajax requests to finish before calling another function.

我对使用jQuery.when()来等待多个ajax请求完成后再调用另一个函数有意见。

Each ajax request will get JSON data, and looks something like this:

每个ajax请求都会得到JSON数据,并且看起来如下:

   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.

当调用请求时,返回值(ajaxCall)被添加到名为ajaxrequest的列表中。

    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.

当所有请求都发出后,我尝试将ajaxRequests传递到$。何时为等待所有请求完成。

        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.

inst是一个基于JSON数据加载和绘制图形的对象。

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.

问题是,它似乎并不是在等待请求完成——args[i]是一个对象,但是当代码运行时responseText是未定义的。如果我保存args[I]并稍后从控制台访问它,它就会工作。

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).

我不确定是否使用apply是正确的想法,但无论哪种方式,它都不能正常工作,并且行为不稳定(依赖于浏览器)。

Any help would be greatly appreciated.

如有任何帮助,我们将不胜感激。

Please let me know if more information is required.
I'm using jQuery 1.5

如果需要更多的信息,请告诉我。我使用jQuery 1.5

4 个解决方案

#1


32  

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.

虽然亚历克斯确实为他的问题提供了一个解决方案,但我发现跟踪这个问题有点困难。我有一个与他的问题类似的问题,我解决了这个问题,我想把我的解决方案分享给其他需要处理大量ajax请求的人。

// 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


9  

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:

除了Andy Corman的回复(我想我还不能回复一个帖子),如果你只有一个请求,回复信息会直接传递给延迟。作为一个论证的功能;所以你需要提供一个if:

// 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


4  

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.

我想我已经算出来了——问题是处理返回的参数。do只通过三个参数——响应文本、状态和jqXHR对象。我期望它通过每个查询产生的jqXHR对象。

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().

通过将每个查询的回调代码移动到一个单独的函数(例如,loadData中的ajax调用现在指定了一个回调函数,该函数执行“.loadData(…)”调用),我已经解决了这个问题。这似乎运行得很好:每个回调都是在.done()之前执行的。

I'm not sure if that's exactly how it's supposed to work, but it seems to be doing the job.

我不确定这是不是它应该的工作方式,但它似乎在做这个工作。

#4


1  

Try ajaxStart and ajaxStop, which have listeners for open ajax requests.

试试ajaxStart和ajaxStop,它们有用于打开ajax请求的侦听器。

http://api.jquery.com/ajaxStart/ http://api.jquery.com/ajaxStop/

http://api.jquery.com/ajaxStart/ http://api.jquery.com/ajaxStop/

#1


32  

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.

虽然亚历克斯确实为他的问题提供了一个解决方案,但我发现跟踪这个问题有点困难。我有一个与他的问题类似的问题,我解决了这个问题,我想把我的解决方案分享给其他需要处理大量ajax请求的人。

// 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


9  

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:

除了Andy Corman的回复(我想我还不能回复一个帖子),如果你只有一个请求,回复信息会直接传递给延迟。作为一个论证的功能;所以你需要提供一个if:

// 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


4  

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.

我想我已经算出来了——问题是处理返回的参数。do只通过三个参数——响应文本、状态和jqXHR对象。我期望它通过每个查询产生的jqXHR对象。

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().

通过将每个查询的回调代码移动到一个单独的函数(例如,loadData中的ajax调用现在指定了一个回调函数,该函数执行“.loadData(…)”调用),我已经解决了这个问题。这似乎运行得很好:每个回调都是在.done()之前执行的。

I'm not sure if that's exactly how it's supposed to work, but it seems to be doing the job.

我不确定这是不是它应该的工作方式,但它似乎在做这个工作。

#4


1  

Try ajaxStart and ajaxStop, which have listeners for open ajax requests.

试试ajaxStart和ajaxStop,它们有用于打开ajax请求的侦听器。

http://api.jquery.com/ajaxStart/ http://api.jquery.com/ajaxStop/

http://api.jquery.com/ajaxStart/ http://api.jquery.com/ajaxStop/