I have a slider which is sending its value to a web server by using the following li开发者_StackOverflow中文版ne of code:
window.location = "http://172.20.2.1:83/trigger/1?" + value;
This code is within my TestSlider(value) function which is called from the onchange event from a range.
The problem is, of course when I move the slider, I am sending vast amounts of data to the web server.
I would like to create a buffer which sends the most recent value. I have created a timer function which for the moment I am happy for it to tick once a second. It should take the public variable Value and just for the moment write it to the log.
The problem I am seeing however is that it is still writing massive amounts of data to the log, so it will of course crash my web server.
Here is my javascript:
//Put a timer in to work as buffer. This should stop the lpc crashing. I think its
//as a result of to much data.
var c=0;
var t;
var timer_is_on=0;
// Holy Smoke Hacked...liked a pro!
calculateHost();
var ip = getControllerIP();
var triggerNumber = 1;
var Value;
function timedCount()
{
//console.log("Timer Ticked: " + c + "URL : " + url); //Write tick value and url to log.
c=c+1; //Add 1 to tick value.
t=setInterval("timedCount()",10000); //Set the old interval.
console.log(c);
}
function doTimer()
{
timer_is_on=1;
timedCount();
}
function testSlider(value)
{
var url = (ip + "/trigger/" + triggerNumber + "?" + value);
//Removed because its it would be better to see when the timer is executing.
//console.log(url);
Value = value;
//Removed because we need a buffer.
//window.location = "http://172.20.2.1:83/trigger/1?" + value;
}
The solution is called debouncing.
The idea is to only react to the last of a series of repeating events.
Read all about debouncing events here: http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
An alternative solution is to throttle the events and thus only react to the events every set interval.
You can use the following function prototype extension to throttle event handlers, look for debouncing logic in the above link:
Function.prototype.throttle = function throttle(delay) {
var func = this, timeOfLastExec = 0, execWaiting = false;
return function throttled() {
var context = this, args = arguments, timeSinceLastExec = new Date().getTime() - timeOfLastExec;
function exec() {
execWaiting && clearTimeout(execWaiting);
execWaiting = false;
timeOfLastExec = new Date().getTime();
func.apply(context, args);
}
if (timeSinceLastExec >= delay) {
exec();
}
else if (!execWaiting) {
execWaiting = setTimeout(exec, delay - timeSinceLastExec);
}
};
};
I think a better way to do this is to use the onMouseUp
event - this will only send data to the server when the slider is released, thereby only sending one request.
The problem with your timer is that you are starting anothering timer in the handler for the timer event. After the first round you have two timers, then four, eight, 16, 32, 64, 128, 256, 512, and so on... After not so very long you will have more timers than the browser has time to hande, all sending data to your server (if you had implemented that yet).
精彩评论