14

我对 Javascript/jquery 世界完全陌生,需要一些帮助。现在,我正在编写一个 html 页面,我必须在其中进行 5 次不同的 Ajax 调用来获取数据以绘制图形。现在,我这样调用这 5 个 ajax 调用:

$(document).ready(function() {
    area0Obj = $.parseJSON($.ajax({
        url : url0,
        async : false,
        dataType : 'json'
    }).responseText);

    area1Obj = $.parseJSON($.ajax({
        url : url1,
        async : false,
        dataType : 'json'
    }).responseText);
.
.
.
    area4Obj = $.parseJSON($.ajax({
        url : url4,
        async : false,
        dataType : 'json'
    }).responseText);

    // some code for generating graphs

)} // closing the document ready function 

我的问题是,在上述情况下,所有的 ajax 调用都是连续进行的。也就是说,在 1 次调用完成后 2 次启动,当 2 次完成时 3 次启动,依此类推.. 每个 Ajax 调用大约需要 5-6 秒来获取数据,这使得整个页面在大约 30 秒内加载.

我尝试将异步类型设置为 true,但在这种情况下,我没有立即获取数据来绘制违背我的目的的图表。

我的问题是:如何使这些调用并行,以便我开始并行获取所有这些数据并且可以在更短的时间内加载我的页面?

提前致谢。

4

9 回答 9

27

使用jQuery.when(延迟):

$.when( $.ajax("/req1"), $.ajax("/req2"), $.ajax("/req3") ).then(function(resp1, resp2, resp3){ 
    // plot graph using data from resp1, resp2 & resp3 
});

回调函数仅在所有 3 个 ajax 调用都完成时调用。

于 2012-09-14T19:21:04.917 回答
2

您不能使用async: false- 代码同步执行,正如您已经知道的那样(即,直到前一个操作完成,操作才会开始)。
你会想要设置async: true(或者只是省略它——默认情况下它是真的)。然后为每个 AJAX 调用定义一个回调函数。在每个回调中,将接收到的数据添加到数组中。然后,检查是否所有数据都已加载(arrayOfJsonObjects.length == 5)。如果有,请调用一个函数来对数据执行任何操作。

于 2012-09-14T18:15:13.863 回答
1

让我们尝试以这种方式进行:

<script type="text/javascript" charset="utf-8">
    $(document).ready(function() {
        var area0Obj = {responseText:''};
        var area1Obj = {responseText:''};
        var area2Obj = {responseText:''};

        var url0 = 'http://someurl/url0/';
        var url1 = 'http://someurl/url1/';
        var url2 = 'http://someurl/url2/';

        var getData = function(someURL, place) {
            $.ajax({
                type     : 'POST',
                dataType : 'json',
                url      : someURL,
                success  : function(data) {
                    place.responseText = data;
                    console.log(place);
                }
            });
        }

        getData(url0, area0Obj);
        getData(url1, area1Obj);
        getData(url2, area2Obj);

    }); 
</script>

如果服务器端将是 smth。像这样:

public function url0() {
    $answer = array(
        array('smth' => 1, 'ope' => 'one'),
        array('smth' => 8, 'ope' => 'two'),
        array('smth' => 5, 'ope' => 'three')
    );
    die(json_encode($answer));
}

public function url1() {
    $answer = array('one','two','three');
    die(json_encode($answer));
}

public function url2() {
    $answer = 'one ,two, three';
    die(json_encode($answer));
}

因此,如您所见,创建了一个函数 getData() 用于从服务器获取数据,然后调用了 3 次。结果将以异步方式接收,例如,第一个可以得到第三个呼叫的答案,最后一个可以得到第一个呼叫。

控制台答案将是:

[{"smth":1,"ope":"one"},{"smth":8,"ope":"two"},{"smth":5,"ope":"three"}]

["one","two","three"]

"one ,two, three"

PS。请阅读:http ://api.jquery.com/jQuery.ajax/在那里您可以清楚地看到有关异步的信息。默认异步参数值 = true。

默认情况下,所有请求都是异步发送的(即默认设置为true)。如果您需要同步请求,请将此选项设置为 false。跨域请求和 dataType: "jsonp" 请求不支持同步操作。请注意,同步请求可能会暂时锁定浏览器,在请求处于活动状态时禁用任何操作...

于 2012-09-14T18:34:51.120 回答
1

以下对我有用 - 我有多个需要传递序列化对象的 ajax 调用:

    var args1 = {
        "table": "users",
        "order": " ORDER BY id DESC ",
        "local_domain":""
    }
    var args2 = {
        "table": "parts",
        "order": " ORDER BY date DESC ",
        "local_domain":""
    }

    $.when(
        $.ajax({
                url: args1.local_domain + '/my/restful',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                type: "POST",
                dataType : "json",
                contentType: "application/json; charset=utf-8",
                data : JSON.stringify(args1),
                error: function(err1) {
                    alert('(Call 1)An error just happened...' + JSON.stringify(err1));
                }
            }),
        $.ajax({
            url: args2.local_domain + '/my/restful',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            type: "POST",
            dataType : "json",
            contentType: "application/json; charset=utf-8",
            data : JSON.stringify(args2),
            error: function(err2) {
                calert('(Call 2)An error just happened...' + JSON.stringify(err2));
            }
        })                     

    ).then(function( data1, data2 ) {
        data1 = cleanDataString(data1);
        data2 = cleanDataString(data2);

        data1.forEach(function(e){
            console.log("ids" + e.id)
        });
        data2.forEach(function(e){
            console.log("dates" + e.date)
        });

    })

    function cleanDataString(data){
            data = decodeURIComponent(data);
            // next if statement was only used because I got additional object on the back of my JSON object
            // parsed it out while serialised and then added back closing 2 brackets
            if(data !== undefined && data.toString().includes('}],success,')){ 
                temp = data.toString().split('}],success,');
                data = temp[0] + '}]';
            }
            data = JSON.parse(data);
            return data;                    // return parsed object
      }
于 2019-09-25T15:01:38.337 回答
0

在 jQuery.ajax 中,您应该提供如下回调方法:

j.ajax({
        url : url0,
        async : true,
        dataType : 'json',
        success:function(data){
             console.log(data);
        }
    }

或者你可以直接使用

jQuery.getJSON(url0, function(data){
  console.log(data);
});

参考

于 2012-09-14T18:14:42.753 回答
0

您将无法像您的示例那样处理它。设置为异步使用另一个线程发出请求并让您的应用程序继续。

在这种情况下,您应该使用一个新函数来绘制一个区域,然后使用 ajax 请求的回调函数将数据传递给该函数。

例如:

$(document).ready(function() {
    function plotArea(data, status, jqXHR) {
      // access the graph object and apply the data.
      var area_data = $.parseJSON(data);
    }

    $.ajax({
        url : url0,
        async : false,
        dataType : 'json',
        success: poltArea
    });

    $.ajax({
        url : url1,
        async : false,
        dataType : 'json',
        success: poltArea
    });

    $.ajax({
        url : url4,
        async : false,
        dataType : 'json',
        success: poltArea
    });

    // some code for generating graphs

}); // closing the document ready function 
于 2012-09-14T18:19:57.320 回答
0

看起来您需要异步分派您的请求并定义一个回调函数来获取响应。

就像你做的那样,它会等到变量被成功分配(意思是:响应刚刚到达),直到它继续分派下一个请求。只需使用这样的东西。

$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: function(data) {
     area0Obj = data;
  }
});

这应该可以解决问题。

于 2012-09-14T18:23:18.970 回答
0

您可以将不同 ajax 函数的所有功能组合成 1 个 ajax 函数,或者从 1 个 ajax 函数调用其他函数(在这种情况下它们将是私有/控制器端),然后返回结果。Ajax 调用确实有点停滞,所以尽量减少它们是要走的路。

您还可以使 ajax 函数异步(然后将像普通函数一样运行),然后您可以在所有函数返回它们的数据后最后渲染图形。

于 2012-09-14T18:35:28.977 回答
0

这是您的问题的解决方案:http: //jsfiddle.net/YZuD9/

于 2012-09-14T18:35:45.947 回答