进行同步和异步ajax调用

时间:2015-03-26 21:54:15

标签: jquery ajax

我对ajax很新,并尝试进行ajax调用。

我必须使用asynch: false,因为如果我不这样做,控件将不会等待来自url的结果,因此不会呈现任何内容。现在我需要再次调用另一个{{1}我不希望ajax在调用url时等待function的结果。我如何使用当前的scenriao执行此操作,我强行必须保留function2以便它首先从servlet获取结果然后尝试渲染?

问题:当ajax进行异步调用时,数据无法呈现。

我想要的是什么:我希望能够进行异步调用,因为我必须在同一个html页面上使用不同的URL来渲染来自不同函数的图表。

我不想要的东西:我不想让它先等待function1呈现结果,然后再调用async:offfunction2function1彼此独立,使用不同的function2来检索数据,因此应该被称为并行y,而不必浪费时间等待一个函数完成并首先渲染数据。

我的代码正在做什么: 1.它从网址以url's格式提取数据。

  1. 使用google charts api JSON根据visualizationJSON格式提供的数据呈现图表。
  2. 到目前为止,此处只有urlfunction。但我需要添加其他功能,以便能够从另一个网址获取另一个图表的数据。

    这是我到目前为止所尝试的内容:

    var queryObjectLen="";
                $.ajax({
                    type : 'POST',
                    async: false,
                    url : 'http://localhost:8080/Charts/db',
                    success : function(data) {
                        queryObject = jQuery.parseJSON(data);            
                        queryObjectLen = queryObject.Details.length;
    
    
                      google.load('visualization', '1.0', {'packages':['corechart']});
    
    
                      google.setOnLoadCallback(drawChart);
                    },
                    error : function(xhr, type) {
                        console.error("OOPS!, an error Occured");
                        alert('server error occoured')
                    }
                });
    

    不使用asynch :false,图表不会呈现,所以我认为这是因为控件继续渲染而不从网址中检索数据,这可能就是它在异步关闭时呈现的原因。但是,我不希望从两个不同的URL检索结果并在此基础上呈现图表。但是,我不想等待一个函数去,获取数据,渲染然后移动到function2,我的意思是它必须是异步调用。我似乎哪里出错了,我不得不强迫它同步,我可以做些什么来做到这一点?

    Edit1:以下是我文件中的完整代码:                                               

             <script type="text/javascript">
    
                var queryObject="";
                var queryObjectLen="";
                $.ajax({
                    type : 'POST',
                    async: false,
                    url : 'http://localhost:8080/DBCHART/db',
                    success : function(data) {
    
                        queryObject = jQuery.parseJSON(data);            
                        queryObjectLen = queryObject.Details.length;
    
    
                      google.load('visualization', '1.0', {'packages':['corechart']});
    
    
                      google.setOnLoadCallback(drawChart);
                    },
                    error : function(xhr, type) {
                        console.error("OOPS!, an error Occured");
    
                        alert('server error occoured')
                    }
                });
    
    
    
                function drawChart()
                {
    
    
                    var arrdata = new google.visualization.DataTable();
                    arrdata.addColumn('string', 'DeptName');
                    arrdata.addColumn('number', 'NumberOfEmployees');
    
                    for(var i=0; i<queryObjectLen; i++)
                    {
                        console.log(queryObject.Details[i].DeptName);
                        var dept= queryObject.Details[i].DeptName;
    
                        var emp = queryObject.Details[i].NumberOfEmployees;
    
                         arrdata.addRows([
                            [dept,parseInt(emp)]
                        ]);
                    }
    
    
        var options = {
                        title: 'Department vs. Number of Employees on Horizontal Axis',
                        vAxis: {title: 'DeptName',  titleTextStyle: {color: 'red'}},
                        'width':400,
                        'height':300
                    };
                    var option2 = {
                    title: 'Department vs. Number of Employees on vertical Axis',
                    hAxis: {title: 'NumberOfEmployees',  titleTextStyle: {color: 'blue'}},
                    'width':400,
                    'height':300
                    };
    
                    var option3 = {
                    title: 'Department vs. Number of Employees on Pie Chart',
                    'width':400,
                    'height':300
                    };
                    var option4 = {
                    title: 'Department vs. Number of Employees on Line Chart',
                    'width':400,
                    'height':300
                    };
               var chart = new google.visualization.BarChart(document.getElementById('chart_div'));//this is altogether a different object
               var chart2 = new google.visualization.ColumnChart(document.getElementById('chart_div2'));
                var chart3 = new google.visualization.PieChart(document.getElementById('chart_div3'));
               var chart4 = new google.visualization.LineChart(document.getElementById('chart_div4'));
                chart.draw(arrdata, options);
                chart2.draw(arrdata, option2);
                chart3.draw(arrdata, option3);
                chart4.draw(arrdata, option4);
            }
    
        </script>
      </head>
    
      <body>
        <div id="chart_div" style="width: 400px; height: 300px;"></div>
        <div id="chart_div2" style="width: 800px; height: 400px;"></div>
        <div id="chart_div3" style="width: 400px; height: 300px;"></div>
        <div id="chart_div4" style="width: 400px; height: 500px;"></div>
    
    
      </body>
    </html>
    

2 个答案:

答案 0 :(得分:1)

感谢Joe理解这个问题。

这是Joe的答案中的性能改进,它加载Google的内容并且并行执行Ajax调用,然后在两者完成时调用drawChart()。这可以做到,因为在开始Ajax调用之前无需等待Google的事情完成,反之亦然。这使用jQuery promises使等待多个异步操作变得容易。

// jQuery promisified version of google.setOnLoadCallback()
function googleSetOnLoadCallbackPromise() {
    return $.Deferred(function(def) {
        google.setOnLoadCallback(function() {
            def.resolve();
        });
    }).promise();
}

google.load('visualization', '1.0', {'packages':['corechart']});
// first promise from the ajax call
var p1 = $.ajax({
    type : 'POST',
    url : 'http://localhost:8080/DBCHART/db'
});
// second promise from loading the Google stuff
var p2 = googleSetOnLoadCallbackPromise();

// use $.when() to know when both promises are done
$.when(p1, p2).then(function(ajaxResult) {
    // ajaxResult is [data, statusText, jqXHR ]
    // so ajaxResult[0] is the data
    queryObject = jQuery.parseJSON(ajaxResult[0]);            
    queryObjectLen = queryObject.Details.length;
    drawChart();
}, function(err) {
    console.error("OOPS!, an error Occured");
    alert('server error occoured')
});

而且,这是一个手动完成的并行版本(不使用promises):

var remainingCntr = 2;
function checkDone() {
    if (--remainingCntr === 0) {
        drawChart();
    }
}

google.load('visualization', '1.0', {'packages':['corechart']});
google.setOnLoadCallback(checkDone);
$.ajax({
    type : 'POST',
    url : 'http://localhost:8080/DBCHART/db',
    success : function(data) {
        queryObject = jQuery.parseJSON(data);            
        queryObjectLen = queryObject.Details.length;
        checkDone();
    },
    error : function(xhr, type) {
        console.error("OOPS!, an error Occured");
        alert('server error occoured')
    }
});

仅供参考,对于我来说,将数据填充到全局变量然后调用使用这些全局变量的drawChart()对我来说感觉非常糟糕。如果这是drawChart()被调用的唯一地方,那么数据可能只是作为参数直接传递给drawChart()

答案 1 :(得分:0)

setOnLoadCallback功能让你现在感到悲痛。这是Google的东西的初始化函数,有点像jQuery&#39; $(document).ready - 你不应该在成功处理程序中使用它,而是包装整个AJAX调用:< / p>

google.load('visualization', '1.0', {'packages':['corechart']});
google.setOnLoadCallback(function() {
    $.ajax({
        type : 'POST',
        url : 'http://localhost:8080/DBCHART/db',
        success : function(data) {
            queryObject = jQuery.parseJSON(data);            
            queryObjectLen = queryObject.Details.length;
            drawChart();
        },
        error : function(xhr, type) {
            console.error("OOPS!, an error Occured");
            alert('server error occoured')
        }
    });
});

完成此操作后,您将能够添加更多异步调用,或者执行您需要执行的任何操作。