Reputation: 715
So I have a wee javascript app that receives a pair of numbers from a server every minute (or whatever) and over the course of the minute it updates a div every second (or whatever) so that the value shown in the div gradually increments from the first value to the second. It's only short, I'll post the code at the bottom of the question.
The function contains two sub functions - one of them does the ajax call to update the two values, one of them updates the div contents with a value somewhere between the two values. The ajax function uses setInterval to schedule the div updating function when it has the response from the server, and when the div updating function detects that it's time to update the two values it clears the set interval and calls the ajax function. These two functions thus carry on calling each other for ever.
I declared every variable used by the two sub functions in the outer function, so neither sub function creates any new variables, and both sub-functions are allowed to finish completely each time anyway (thanks to the setInterval in the ajax function).
The memory usage is going up almost every second, which must be every time doDivRefresh is called, but I don't understand what it's doing with new memory each time it's called - it doesn't create any variables.
Help!
/**
*
* Periodically gets the latest values for a stat and changes the contents of a
* div so that is ticks up from the previous value to the latest value
*
* @param divID
* The id of the div to update
* @param URL
* The URL that provides the values
* @param updateDivFrequency
* How often the value displayed in the div is updated, in
* miliseconds
* @param updateDataFrequency
* How often the underlying data is updated from the server, in
* seconds
*
*/
function updateStatOverPeriod(divID, URL, updateDivFrequency, updateDataFrequency)
{
var somethingDoer = new function()
{
};
var request = new XMLHttpRequest();
var currentValue = "";
var previousValue = "";
var latestValue = "";
var it = 0;
var currentTime = new Date();
var endTime = new Date().getTime();
function doDivRefresh(endTime)
{
if (currentValue != null)
{
currentValue = currentValue + it;
document.getElementById(divID).innerHTML = addCommas(parseInt(currentValue));
}
else
{
document.getElementById(divID).innerHTML = "<DIV CLASS=\"error_message\">No data</DIV>";
}
// If it's time to refresh the data end this loop and call the starting
// off method again
currentTime = new Date();
if (currentTime.getTime() >= endTime)
{
clearInterval(somethingDoer);
doAJAX();
}
}
function doAJAX()
{
// If browser supports javascript
if (window.XMLHttpRequest)
{
// Connect to the server and get the new pair of values
request = new XMLHttpRequest();
request.open('get', URL);
request.onreadystatechange = function()
{
// Once...
if (request.readyState == 4)
{
// we've got...
if (request.status == 200)
{
// the response
if (request.responseText)
{
// Parse the response and work out our iterator
previousValue = parseFloat(request.responseText.split("&")[0]);
latestValue = parseFloat(request.responseText.split("&")[1]);
if ((previousValue == 0) || (latestValue == 0))
{
it = parseFloat('0.00');
}
else
{
it = parseFloat((latestValue - previousValue) / (updateDataFrequency / updateDivFrequency));
}
// Set up the doRefreshDiv function in a loop that
// will exit and re-call this function
// once updateDataFrequency has elapsed
currentValue = previousValue;
endTime = new Date().getTime() + updateDataFrequency;
doDivRefresh(endTime);
somethingDoer = setInterval(function()
{
doDivRefresh(endTime);
}, updateDivFrequency);
alert("end of ajax response function()");
}
else
{
document.getElementById(divName).innerHTML = "<DIV CLASS=\"error_message\">Error - no data received from server</DIV>";
}
}
else
{
document.getElementById(divName).innerHTML = "<DIV CLASS=\"error_message\">Error - server returned " + request.status + "</DIV>";
}
}
};
request.send(null);
}
else
{
console.error("No window.XMLHttpRequest, does this browser support AJAX?");
}
alert("end of doAJAX()");
}
// Start
updateDataFrequency = updateDataFrequency * 1000;
doAJAX();
}
Upvotes: 0
Views: 992
Reputation: 715
[head slap]
Thanks for the answers guys, but the real problem was a typo in the element calling the script. Due to a / where I meant to put a * the script was being called about once a millisecond instead of once a minute as intended!
Upvotes: 0
Reputation: 2564
I agree that new Date()
is always going to be costly. Now here as you just want this code to be executed to refresh values at regular interval can you use setTimeout("doAJAX()",2000);
and you can specify the interval in milliseconds instead of checking it using a date function. That should help and in another case you can well use jquery.Ajax if you're interested because there you will be able to concentrate on your area of interest instead of dealing with XMLHttpRequest
by yourself.
Upvotes: 0
Reputation: 41050
These are the first four lines corrected according to jslint.com:
function updateStatOverPeriod(divID, URL, updateDivFrequency, updateDataFrequency) {
"use strict";
var somethingDoer = function() {};
var request = new XMLHttpRequest();
Paste your code there and check for common JS errors. It seems this code was either transformed from an other language to JavaScript or somebody who is not familiar with JavaScript...
See my answer javascript memory leak for dealing with memory leaks. I still think Drip is a very good tool for finding and understanding memory leaks.
Upvotes: 1