我对ajax很新,并尝试进行ajax调用。
我必须使用asynch: false
,因为如果我不这样做,控件将不会等待来自url
的结果,因此不会呈现任何内容。现在我需要再次调用另一个{{1}我不希望ajax在调用url
时等待function
的结果。我如何使用当前的scenriao执行此操作,我强行必须保留function2
以便它首先从servlet获取结果然后尝试渲染?
问题:当ajax进行异步调用时,数据无法呈现。
我想要的是什么:我希望能够进行异步调用,因为我必须在同一个html页面上使用不同的URL来渲染来自不同函数的图表。
我不想要的东西:我不想让它先等待function1呈现结果,然后再调用async:off
。 function2
和function1
彼此独立,使用不同的function2
来检索数据,因此应该被称为并行y,而不必浪费时间等待一个函数完成并首先渲染数据。
我的代码正在做什么:
1.它从网址以url's
格式提取数据。
JSON
根据visualization
以JSON
格式提供的数据呈现图表。到目前为止,此处只有url
个function
。但我需要添加其他功能,以便能够从另一个网址获取另一个图表的数据。
这是我到目前为止所尝试的内容:
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>
答案 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')
}
});
});
完成此操作后,您将能够添加更多异步调用,或者执行您需要执行的任何操作。