I'm wondering if there's a way to make setInterval clear itself.
Something like this:
setInterval(function () {
alert(1);
clearInterval(this);
}, 2000);
I want it to keep checking thing if it's finished it will stop.
Try this way:
var myInterval = setInterval(function () {
alert(1);
clearInterval(myInterval);
}, 2000);
Alternative way is using setTimeout() if you know it is just one time call.
(function() {
var runs = 3;
var i = setInterval(function() {
console.log("Number " + runs);
--runs;
if (runs == 0) {
clearInterval(i);
}
}, 1000);
}());
jsfiddle
Related
I have a strange problem, well I'm trying to make a loop using setInterval but i want to have a SetTimeout inside as well.
Seems, from the comments, what you need is just
var init = function() {
setTimeout(function(){
console.log("Hi");
init(); // only call init here to start again if need be
}, 8000);
}
init();
based on the comment below, I'm assuming the interval needs to be "paused" sometimes because in your comment you say at some point, I have to delay one action - which implies that this delay isn't always necessary. Given that, you could write it as follows
var test = function() {
var interval = setInterval(function() {
if (someCondition) {
clearInterval(interval); // stop the interval
setTimeout(function(){
console.log("Hi");
test(); // restart the interval
}, 8000);
} else {
// this is done every second, except when "someCondition" is true
}
}, 1000);
}
or even
var running = true;
var test = function() {
var interval = setInterval(function() {
if (someCondition) {
running = false; // stop the interval
setTimeout(function(){
console.log("Hi");
running = true; // restart the interval
}, 8000);
} else if (running) {
// this is done every second, only when "running" is true
}
}, 1000);
}
I want to execute a block of code every two seconds—to accomplish this, I thought the easiest way would be to retrieve the current system time as so:
if ((Date().getSeconds()) % 2 == 0) {
alert("hello"); //I want to add code here!
}
However, my alert is not printing to the screen every two seconds. How can this be properly implemented?
In order to run a block of code every x seconds, you can use setInterval.
Here's an example:
setInterval(function(){
alert("Hello");
}, x000); // x * 1000 (in milliseconds)
Here's a working snippet:
setInterval(function() {
console.log("Hello");
}, 2000);
You can use setInterval(). This will loop every 2 seconds.
setInterval(function() {
//something juicy
}, 2000);
Try using the setInterval() method
setInterval(function () {console.log('hello'); }, 2000)
This should work for you.
setInterval(function() {
//do your stuff
}, 2000)
However, to answer why your code is not working, because it is not in a loop.
runInterval(runYourCodeHere, 2);
function runInterval(callback, interval) {
var cached = new Array(60);
while (true) {
var sec = new Date().getSeconds();
if (sec === 0 && cached[0]) {
cached = new Array(60);
}
if (!cached[sec] && sec % interval === 0) {
cached[sec] = true;
callback();
}
}
}
function runYourCodeHere() {
console.log('test');
}
myInterval = setInterval(function(){
MyFunction();
},50);
function MyFunction()
{
//Can I call clearInterval(myInterval); in here?
}
The interval's not stopping (not being cleared), if what I've coded above is fine then it'll help me look elsewhere for what's causing the problem. Thanks.
EDIT: Let's assume it completes a few intervals before clearInterval is called which removes the need for setTimeout.
As long as you have scope to the saved interval variable, you can cancel it from anywhere.
In an "child" scope:
var myInterval = setInterval(function(){
clearInterval(myInterval);
},50);
In a "sibling" scope:
var myInterval = setInterval(function(){
foo();
},50);
var foo = function () {
clearInterval(myInterval);
};
You could even pass the interval if it would go out of scope:
var someScope = function () {
var myInterval = setInterval(function(){
foo(myInterval);
},50);
};
var foo = function (myInterval) {
clearInterval(myInterval);
};
clearInterval(myInterval);
will do the trick to cancel the Interval whenever you need it.
If you want to immediately cancel after the first call, you should take setTimeout instead. And sure you can call it in the Interval function itself.
var myInterval = setInterval(function() {
if (/* condition here */){
clearInterval(myInterval);
}
}, 50);
see an EXAMPLE here.
var interval = setInterval(function() {
if (condition) clearInterval(interval); // here interval is undefined, but when we call this function it will be defined in this context
}, 50);
Or
var callback = function() { if (condition) clearInterval(interval); }; // here interval is undefined, but when we call this function it will be defined in this context
var interval = setInterval(callback, 50);
From your code what seems you want to do is to run a function and run it again and again until some job is done...
That is actually a task for the setTimeout(), the approach is similar:
var myFunction = function(){
if( stopCondition ) doSomeStuff(); //(do some stuff and don't run it again)
else setTimeout( myFunction, 50 );
}
myFunction(); //immediate first run
Simple as that :)
Of course if you REALLY want to use setInterval for some reason, #jbabey's answer seems to be the best one :)
You can do it by using a trick with window.setTimeout
var Interval = function () {
if (condition) {
//do Stuff
}
else {
window.setTimeout(Interval, 20);
};
};
window.setTimeout(Interval, 20);
I think I might be overtired but I cannot for the life of me make sense of this, and I think it's due to a lack of knowledge of javascript
var itv=function(){
return setInterval(function(){
sys.puts('interval');
}, 1000);
}
var tout=function(itv){
return setTimeout(function(){
sys.puts('timeout');
clearInterval(itv);
}, 5500);
}
With these two functions I can call
a=tout(itv());
and get a looping timer to run for 5.5 seconds and then exit, essentially.
By my logic, this should work but it simply is not
var dotime=function(){
return setTimeout(function(){
clearInterval(function(){
return setInterval(function(){
sys.puts("interval");
}, 1000);
});
}, 5500);
}
any insight in this matter would be appreciated.
it cannot work because because your setInterval will be called AFTER the timeout! your original approach is correct and you can still wrap this into single function:
var dotime=function(){
var iv = setInterval(function(){
sys.puts("interval");
}, 1000);
return setTimeout(function(){
clearInterval(iv);
}, 5500);
};
I think the mistake you're making is that the function itv doesn't return setInterval(function(){ sys.puts('interval'); }, 1000) it executes setInterval(function(){ sys.puts('interval'); }, 1000) and than returns back an ID that setInterval generates. That ID is then passed to the clearInterval function to stop what setInterval(function(){ sys.puts('interval'); }, 1000) is doing.
Edit: An example of one function that would work.
var dotime=function(){
// Start our interval and save the id
var intervalId = setInterval(function(){
// This will get executed every interval
sys.puts("interval");
}, 1000);
// Start our timout function
setTimeout(function(){
// This will get executed when the timeout happens
clearInterval(intervalId); // Stop the interval from happening anymore
}, 5500);
}
This is another way to write your version, you see that you pass a function to clearInterval, where you should have passed it a timer id.
var dotime=function(){
var g=function(){
var f=function(){
return setInterval(function(){
sys.puts("interval");
}, 1000);
}
clearInterval(f);
}
return setTimeout(g, 5500);
}
To make it work you shoud call the function :
clearInterval(f());
Or, using your version :
var dotime=function(){
return setTimeout(function(){
clearInterval(function(){
return setInterval(function(){
sys.puts("interval");
}, 1000);
}());
}, 5500);
}
Disclaimer : I didn't test this.
I need to flash an element off and on. This works but I don't really like the code. Is there a nice way of doing this?
setTimeout(function(){
toggle();
setTimeout(function(){
toggle();
setTimeout(function(){
toggle();
setTimeout(function(){
toggle();
}, 100);
}, 100);
}, 100);
}, 100);
I'm using jQuery too if that helps.
function toggle_multiple(n)
{
var toggled = 0;
function toggle_one_time()
{
toggle();
toggled += 1;
if (toggled <= n)
setTimeout(toggle_one_time, 100);
}
toggle_one_time();
}
And just call toggle_multiple(4).
A recursive approach:
function multiTimeoutCall (callback, delay, times) {
if (times > 0){
setTimeout(function () {
callback();
multiTimeoutCall (callback, delay, times - 1);
}, delay);
}
}
Usage:
multiTimeoutCall (toggle, 100, 4);
Edit: Yet another approach, without filling the call stack:
function multiTimeoutCall (callback, delay, times) {
setTimeout(function action() { // a named function expression
callback();
if (--times > 0) {
setTimeout (action, delay); // start a new timer
}
}, delay);
}
I could used arguments.callee instead of a named function expression, but seems that it will be deprecated some day in ECMAScript 5...
Why not use setInterval?
var toggler = function() {
if (++self.counter >= self.BLINK_AMOUNT * 2) {
self.counter = 0;
window.clearInterval(self.timer);
return;
}
toggle();
};
toggler.BLINK_AMOUNT = 1;
toggler.counter = 0;
toggler.timer = window.setInterval(toggler, 100);
I can't remember whether or not IE properly implements the self variable in a timer callback - if it doesn't, use a uniquely named global variable instead.
I would use a blinking effect. For jquery there's pulsate, hope that works for you.
Here's yet another version for simplicity:
for (var i= 0; i<4; i++)
setTimeout(toggle, (i+1)*100);
For larger numbers an interval may be more appropriate, but if it's just four toggles multiple timeouts are fine.
Generalizing 'unknown's' idea of using setInterval,
function schedule(fn, max, delay)
{
var counter = 0;
var interval = setInterval(
function()
{
if(counter++ === max)
clearInterval(interval);
fn();
}
, delay);
}
Usage:
schedule(toggle, 4, 100);
If its just flashing that is required, why not use the jQuery animate ? I use the following to direct user attention to messages. But you can do this for any element -
$("#message_box").fadeOut(450).fadeIn(350);
If you want it multiple times, do this -
$("#message_box").fadeOut(450).fadeIn(350).fadeOut(450).fadeIn(350);
You can do like this:
function toggleMany(cnt) {
toggle();
if (--cnt >= 0) window.setTimeout('toggleMany('+cnt+')', 100);
}
toggleMany(4);