setInterval(this.Animate(), this.speed);
This is expected to be run every this.speed times. Yes, but the browsers run it only one time. What are the possible reasons for that?
Try to run your function without the parentheses, when you put parentheses it always calls the function instead of passing it, which is what you want here:
setInterval(this.Animate, this.speed);
If it still doesn't work, you should debug and find out what is the scope for 'this', as 'this' might change. You can do that by adding a breakpoint in your browser's JS debugger.
Also, you can try this to avoid the scope problem with 'apply'
var animate = this.animate.apply(this)
setInterval(animate, this.speed);
p.s: It might be a good choice to avoid setInterval for animation as they might queue and then fire at once. Instead call setTimedout once and again at the end of the function (this.Animate) as so to create a loop.
If Animate is a derived function from the prototype, you'll have to use:
setInterval(this.Animate.bind(this), this.speed);
Do the following:
setInterval(this.Animate, this.speed);
You are executing the function instead of assigning a reference to the function to be executed at a certain interval...
Let us look at your code
setInterval(this.Animate(), this.speed);
What it is saying is run the function this.Animate() right away and store what ever it returns to be called.
What you want to do is create a closure
var that = this;
setInterval( function(){ that.Animate() }, this.speed);
The that maintains the current scope.
If you're looking for a JQuery refresh script, try:
refreshId = setInterval(function() {
// Events or Actions
}, 5000);
If you ever want to Pause or Stop this, use clear interval: clearInterval(refreshId);.
Related
I'm writing a "Game of Life" in javascript. I have all the logic done in a function called doGeneration(). I can repeatedly call this from the console and everything goes as planned, however, if I put it in a while loop the execution blocks the UI and I just see the end result (eventually).
while (existence) {
doGeneration();
}
If I add a setTimeout(), even with a generation limit of say 15, the browser actually crashes (Canary, Chrome).
while (existence) {
setTimeout(function() {
doGeneration();
},100);
}
How can I call doGeneration() once every second or so without blocking the DOM/UI?
You want setInterval
var intervalId = setInterval(function() {
doGeneration();
}, 1000);
// call this to stop it
clearInterval(intervalId);
I would use requestAnimationFrame(doGeneration). The idea of this function is to let the browser decide at what interval the game logic or animation is executed. This comes with potential benefits.
https://hacks.mozilla.org/2011/08/animating-with-javascript-from-setinterval-to-requestanimationframe/
Rather than using setINterval or setTimeout and assume some random time interval will be enough for the UI to update you shoul/could make the doGeneration smart enough to call itself after dom was updated and if the condition of existence is satisfied.
Suppose I have a callback firing perpetually as the result of some event; i.e. Someone's moving a mouse.
I'd like to run a cleanup action if the callback hasn't fired in x seconds; i.e. If they haven't moved the mouse in 2 seconds, fire.
I think I could probably fix something up with setTimeout, but I'm wondering if any standard libraries have a function for this? Sort of a 'dead-mans-switch', seems like it would be common enough to have a standard method. If not I'm making one. Anyone?
De-bouncing may be a technique that will help.
It is essentially a method of wrapping a function so that you have control over when the wrapped function will execute, regardless of how often the debounced version is called.
This is most commonly used for events, like window resize. Then you can only execute your handler once the user has finished resizing the window rather then whilst they are resizing it.
There is also throttling, this is similar but has important differences.
Throttled functions will execute once every n time rather than a debounced version which will executed after it hasn't be called for n time.
underscore and lodash have implementations of de-bouncing and throttling.
However they it is quite easy to achieve and you don't really need a large library if its not already being used.
I think you're on the right track about setTimeout. As per your wonder, I am not aware of a module that would do it. And due to the intrusive nature of this process, it makes sense.
You could do this tho:
var yourmodule; //assuming you're using a module to store your app code; the object should obviously exist before continuing
yourmodule.cleanupSequenceId = -1;
function yourEventCallback() {
if (yourmodule.cleanupSequenceId !== -1) clearTimeout(yourmodule.cleanupSequenceId);
//function logic
//cleanup:
yourmodule.cleanupSequenceId = setTimeout(cleanupMethod, 2000);
}
After stumbling upon this (very old) question, and reading many others like it, I found a solution that works for me so I wanted to share it.
You define a "Debounce" function like this:
var debounce_timeout // Global debouncer timer, so all calls target this specific timeout.
function debounce(func, delay = 2000) {
clearTimeout(debounce_timeout)
debounce_timeout = setTimeout(() => {
func()
}, delay)
}
Now if you wish to debounce some function, you do:
debounce(myFunction)
Debouncing essentially means, that when your function is called, we observe for 'delay' duration, if any other calls to the function is made. If another call is made, we reset our observing time.
what i need is a for or while loop that will re run the code every second
ive tried sleep() but i dont think it is working or i have got it right
Do not try to use a for or while loop for such timed operations. You'll have a hard time with reliable or accurate timing and usually end up railing the CPU, making the computer sluggish.
JavaScript provides the setInterval() function for these kinds of tasks. Also note that Greasemonkey has some caveats about how to use setInterval() and setTimeout().
So the code you want is like:
var timerVar = setInterval (function() {DoMeEverySecond (); }, 1000);
function DoMeEverySecond ()
{
//--- Your code here.
}
//--- When ready to stop the timer, run this code:
clearInterval (timerVar);
timerVar = "";
try
// where yourfunction is a method that contains your loop logic
setTimeout(yourfunction, 1000);
This will invoke the function every 1000 milliseconds without having to embed it into a while or for loop.
put it into your body onload or similar event
I am having a problem understanding which function runs (probably in infinite loop) in my JS code.
Is there a plug\way to see the list of the setTimeout functions that are running?
All you have to do is hook into your setTimeout function and log stuff:
var _temp = setTimeout;
setTimeout = function() {
_temp.apply(this, arguments);
alert(arguments[0]);
};
Put that snippet at the top of your code. Every time anything invokes setTimeout, you'll see exactly who's doing it.
Also, instead of alert, use console.log or something similar.
You can probably use the Firebug Firefox extension to put a breakpoint in. http://getfirebug.com/
I am trying to call showUpload(); from within two setTimeouts. Neither works. It seems to be out of scope and I'm not sure why. I tried this.showUpload() which didn't work either.
$(document).ready(function(){
var progress_key = $('#progress_key').val();
// this sets up the progress bar
$('#uploadform').submit(function() {
setTimeout("showUpload()",1500);
$("#progressbar").progressbar({ value:0}).fadeIn();
});
// uses ajax to poll the uploadprogress.php page with the id
// deserializes the json string, and computes the percentage (integer)
// update the jQuery progress bar
// sets a timer for the next poll in 750ms
function showUpload() {
$.get("/myid/videos/uploadprogress/" + progress_key, function(data) {
if (!data)
return;
var response;
eval ("response = " + data);
if (!response)
return;
var percentage = Math.floor(100 * parseInt(response['bytes_uploaded']) / parseInt(response['bytes_total']));
$("#progressbar").progressbar({ value:percentage})
});
setTimeout("showUpload()", 750);
}
});
Thank you for your time.
As #Daniel said, this should work:
setTimeout(showUpload, 750);
Please note that the quotes should be removed (this is why it isn't being executed until the timeout runs out). Right now, you are passing a string, which is evaled when the timeout runs out. This eval will happen in a different scope, which is why you are seeing the problem you are seeing.
Instead, passing a reference to the showUpload function to setTimeout will allow your function to be executed later. Keep in mind that when it runs, it will be in a different scope, so you may have other scope issues, like with progress_key. You will need to create a closure around showUpload to capture that parameter.
It looks like you need to remove the parenthesis from showUpload in both your setTimeout calls. Otherwise you will be invoking the showUpload method instead of passing it as a parameter:
setTimeout(showUpload, 750);