问题
I have two different javascript functions as below. When I call these functions, until the function completes executing, I am showing loading image. The problem I am having is that when first function completes, it should load the chart and the second function runs and load the chart.
That's not what's happening. Both charts load when both function completes. I need each function to run and load the chart when each complete not both at the same time.
Here is the functions:
<script>
function vcenter1(){
$('#loading').html('<img src="img/loading.gif"> loading...');
var req = ocpu.rpc("cpu", {
}, function(output){
var data=output;
data=JSON.parse(data);
$('#output').highcharts('StockChart', {
chart: {
borderColor: '#98AFC7',
borderRadius: 20,
borderWidth: 1,
renderTo: 'output',
type: 'line',
marginRight: 30,
zoomType: 'x',
resetZoomButton: {
position: {
x: -50,
y: -40
}
}
},
plotOptions: {
line: {
marker: {
radius: 2,
lineColor: '#666666',
lineWidth: 2
}
}
},
exporting: {
enabled: true
},
legend: {
enabled:true,
layout: 'horizontal',
maxHeight: 55 // max. 2 lines with navigation
},
rangeSelector: {
allButtonsEnabled: true,
inputEnabled: $('#output').width() > 480,
selected: 2
},
scrollbar: {
enabled: false
},
navigator : {
enabled : false
},
xAxis: {
type:'datetime',
gridLineColor: '#EEEEEE',
gridLineWidth: 1
},
yAxis: { // Primary yAxis
min:0,
max:100,
labels: {
style: {
color: "black",
fontWeight: 'bold'
}
},
title: {
text: '% CPU Utilization',
style: {
color: 'black',
fontWeight: 'bold'
}
}
},
credits: {
enabled: false
},
title: {
text: "% CPU UTILIZATION",
style: {
color: '#333000',
fontSize: '18px',
fontWeight: 'bold'
}
},
tooltip: {
useHTML:true,
positioner: function (boxWidth, boxHeight, point) {
return { x: this.chart.plotLeft, y: this.chart.plotTop - 5 };
},
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y} <b>',
valueDecimals: 0
},
series: data
});
});
//if R returns an error, alert the error message
req.fail(function(){
alert("Server error: " + req.responseText);
$('#loading').html('');
});
//after request complete, re-enable the button
req.always(function(){
$('#loading').html('');
});
}
//VCENTER2
function vcenter2(){
$('#loading1').html('<img src="img/loading.gif"> loading...');
var req = ocpu.rpc("memory", {
}, function(output1){
var data1=output1;
data1=JSON.parse(data1);
console.log("Ready to paint 2:");
$('#output1').highcharts('StockChart', {
chart: {
borderColor: '#98AFC7',
borderRadius: 20,
borderWidth: 1,
type: 'line',
marginRight: 20,
zoomType: 'x',
resetZoomButton: {
position: {
x: -50,
y: -40
}
}
},
plotOptions: {
line: {
marker: {
radius: 2,
lineColor: '#666666',
lineWidth: 2
}
}
},
exporting: {
enabled: true
},
legend: {
enabled:true,
layout: 'horizontal',
maxHeight: 55 // max. 2 lines with navigation
},
rangeSelector: {
allButtonsEnabled: true,
inputEnabled: $('#output1').width() > 480,
selected: 2
},
scrollbar: {
enabled: false
},
navigator : {
enabled : false
},
xAxis: {
type:'datetime',
gridLineColor: '#EEEEEE',
gridLineWidth: 1
},
yAxis: { // Primary yAxis
min:0,
max:100,
labels: {
style: {
color: 'black',
fontWeight: 'bold'
}
},
title: {
text: '% Memory Utilization',
style: {
color: 'black',
fontWeight: 'bold'
}
},
opposite: true
},
credits: {
enabled: false
},
title: {
text: "% MEMORY UTILIZATION",
style: {
color: '#333000',
fontSize: '18px',
fontWeight: 'bold'
}
},
tooltip: {
useHTML:true,
positioner: function (boxWidth, boxHeight, point) {
return { x: this.chart.plotLeft, y: this.chart.plotTop - 5 };
},
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y} <b>',
valueDecimals: 0
},
series: data1
});
});
//if R returns an error, alert the error message
req.fail(function(){
alert("Server error: " + req.responseText);
$('#loading1').html('');
});
//after request complete, re-enable the button
req.always(function(){
$('#loading1').html('');
});
}
</script>
This is where I am calling them:
<!-- Placed at the end of the document so the pages load faster -->
<script>
$('a[href*="vmware"]').on('click', function () {
vcenter1();
vcenter2();
});
Any ideas that I am missing here? I need to show loading image why the function is running, when it's completes, I need to show the data and move on to the second function and so forth. Now, what's happening is that first function runs, completes, loading image goes away but no data/chart shows up. Second function runs, completes then both divs are full with data/charts.
回答1:
Look at JavaScript callbacks, or for more functionality, jQuery Deferred - a good tutorial is at http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/.
回答2:
I don't think you understand how the asynchronous calls are working. With your functions here's how the workflow would go:
vcenter1
rpc
async ajax call to R
vcenter2
rpc
async ajax call to R
At some later time, vcenter1's ajax call completes, then -->
always callback - which removes loading
complete callback
parse JSON
render chart
At some later time, vcenter2's ajax call completes, then -->
always callback - which removes loading
complete callback
parse JSON
render chart
If you really want it to run vcenter2 after vcenter1, then the call to vcenter2 needs to be in the complete callback of vcenter1's rpc.
来源:https://stackoverflow.com/questions/25530054/how-do-you-run-two-different-functions-in-javascript