JavaScript not updating before setInterval
Thanks Sean for your help. I have moved the calculation code to its own method as you suggested. After debugging I have realised the problem is something to do with storing values globally. I think I have accidently created closures. I have moved the calculation code into a method named calculate() that is run once so that the values of the variable are set globally. but while the method is running the correct values are set, as soon as the method exits and the move() method is called all the values are set to undefined or 0. In the calculate method I even used a hidden field to set the value ('mills') so that I can pass the interval time to this testTimer = window.setInterval(move,document.getElementById('mills').value,"testTimer"); Code of thecalculate()` method looks like this:-
var duration_equiv_seconds = 0;
var duration_equiv_millsec = 0;
var elapsed_percentage = 0;
var elapsed = 0;
var duration = 0;
// function in one JS file
function calculate () {
duration = document.getElementById('callDuration').value;
elapsed = document.getElementById('callElapsed').value;
duration_equiv_seconds = duration/100;
duration_equiv_millsec = duration_equiv_seconds * 1000;
document.getElementById('mills').value = Number(duration)/100 * 1000 ;
开发者_高级运维elapsed_percentage = (elapsed/duration) * 100;
display_progress(elapsed_percentage);
var countCalc = 0;
document.getElementById('status_message').innerHTML =" CountCalc = " + countCalc + " duration = " + duration + " elapsed =" + elapsed + " elapsed2Var =" + elapsed2Var +" duration_equiv_seconds = " + duration_equiv_seconds + " duration_equiv_millsec=" + duration_equiv_millsec + "
elapsed_percentage=" + elapsed_percentage; countCalc++; return duration_equiv_millsec; }
function voice_progress (time_interval){
// outer timer
voiceTimer = window.setInterval(function(){
handleDurationElapsedRequest()
// outside
function move(){
var count = 0;
duration = document.getElementById('callDuration').value;
elapsed = document.getElementById('callElapsed').value;
duration_equiv_seconds = duration/100;
duration_equiv_millsec = duration_equiv_seconds * 1000;
elapsed = Number(elapsed) + Number(duration_equiv_seconds);
elapsed_percentage = (elapsed/duration) * 100;
document.getElementById('callElapsed').value = elapsed;
display_progress(elapsed_percentage);
move_bar(elapsed_percentage);
if (elapsed_percentage >= 100){
terminate_timer(testTimer);
}
document.getElementById('status_message').innerHTML =" at the endAt the end" + count + " duration = " + duration + " elapsed =" + elapsed +" duration_equiv_seconds = " + duration_equiv_seconds + " duration_equiv_millsec=" + duration_equiv_millsec + " elapsed_percentage=" + elapsed_percentage;
count++;
return duration_equiv_millsec;
}
var sleepTime = calculate(); // sleep time returns 0
testTimer = window.setInterval(move,document.getElementById('mills').value ,"testTimer");
},time_interval,"voiceTimer"); // end of outer Timer (time_interval = 1500) called from <body onload="voice_progress(1500);">
}
//.................................................................`enter code here`
// in another JS file
// XMLHttpObject is created called, server returns the correct values
function handleDurationElapsedRequest(){
if(xmlHttpObject.readyState==4){
if(xmlHttpObject.status==200){
var resp = xmlHttpObject.responseText;
var respArray = resp.split("-");
document.getElementById('callElapsed').value = respArray[0]; //value set here is 47
document.getElementById('callDuration').value = respArray[1]; // value set here is 240
document.getElementById('mills').value = respArray[1]/100 * 1000 ;
}
}
}
The problem is that you are doing the calculations inside of your callback, so that when you start, all of your variables are still 0.
Pull the time calculation out into its own function, and call that before you call setInterval
, and your values will start with the right numbers. (Continue to call it in your callback, of course.)
You also are re-scheduling your setInterval
call inside move
. This is probably wrong, because it will be re-called every interval, so now you have 2 functions being called on a timer. If you use setTimeout
, then you might want to reschedule, but not with setInterval
.
You also have the same calculation done twice -- JavaScript is real code, and you should treat it as such; Pull that out into a function you can call.
-- Edit --
Now call calculate()
from move()
so you don't have the same code in 2 places. ;-)
callDuration
and callElapsed
are only set from handleDurationElapsedRequest
, and only when the request is finished. That's probably why you're getting 0. What exactly are you trying to do here? Is the whole page on line somewhere?
Thanks for help. I have fixed the problem. The problem was I was reading the values 'callDuration' and 'callElapsed' before they were even updated after they have been retrieved from the server. I fixed this by setting a timeout of 1.5 seconds before the code that reads these values is executed ie window.setTimeout("calculate()",1500);
Thanks for the help again.
精彩评论