How to change the period (timer) in setInterval() method without using clearInterval() of that method(Id)?
I want to make the method have an initial fixed speed and slow down over time and with the help of the setTimeout() method to finish in ten seconds for example?
If I could get some examples I would be very grateful :)
I think an interval is the wrong thing to use. You would be better off using setTimeout and call the next timeout based on the new waiting time you want.
function runIt(myFunc) {
let waitFor = 3000;
function executeIt () {
myFunc();
waitFor = waitFor - 250;
if (waitFor>=0) {
next();
}
}
function next() {
window.setTimeout(executeIt, waitFor);
}
next();
}
runIt(function (){ console.log(Date.now())})
Related
I run a function in Javascript asynchronously by using the setinterval function.
myVar = setInterval(myTimer, 5000);
The execution of the myTimer function can be quite long, sometimes longer than the specified delay, in that case the intervals just get executed back to back. I would like the next execution of the callback function to be scheduled in relationship with the end of the execution of the previous. To restate I want the myTimer function to run after 5000 ms of when previous finishes and wanted this to repeat.
Yes this can be done using setTimeout instead.
function myTimer(){
console.log("Exec func");
// Rest of the functionality here
setTimeout(myTimer, 5000);
}
myTimer();
You can do something like that:
function longFunction() {
// Do your stuff here
}
var taskId;
function task() {
longFunction();
taskId = setTimeout(task, 5000);
}
I have an ongoing while loop. In the while loop, there is a setTimeout(). I want to reset the timer AFTER the timer expires. In other words, when timer expires, it should do some specified actions, and then freshly start the timer again.
For example, in the following code, %%--Hi--%% should be printed only ONCE in 5 seconds. However, after 5 seconds, %%--Hi--%% is printed continuously. I tried clearTimeout but it looks like that clearTimeout can stop timer only before timer expires.
while(){
var timeoutHandle = setTimeout(function() {
console.log("%%--Hi--%%");
clearTimeout(timeoutHandle);
},
5000); //5 sec
}
Help please! Thanks!
It's not the timeout that's tripping you up, it's the infinite while loop. You're effectively creating thousands of timeouts every second. Moving the timeout outside of the infinite loop should solve your problem.
function timedAction() {
// your timed actions to be invoked every 5 seconds
setTimeout(timedAction, 5000); // start the next timeout
}
setTimeout(timedAction, 5000); // start the first timeout
while() {
// your continuously executing actions
}
There is no need to clear a timeout after it expires.
Alternatively you could also use setInterval, simplifying your code as follows:
function timedAction() {
// your timed actions to be invoked every 5 seconds
}
setInterval(timedAction, 5000); // start the interval
while() {
// your continuously executing actions
}
try this code:
logFun();
function logFun() {
console.log("%%--Hi--%%");
setTimeout(logFun, 5000);
}
or, you can try setInterval:
setInterval(function () {
console.log("%%--Hi--%%");
}, 5000);
The setTimeout method does not act like a sleep statement. Your while loop will continue to iterate continuously regardless of what time interval you set in the setTimeout method.
You should remove the while and simply use setInterval(). (Mentioned in yibuyisheng's answer. +1)
var myInterval = setInterval(function () {
console.log("%%--Hi--%%");
}, 5000);
If you want to stop the interval, run the following:
clearInterval(myInterval);
Your problem is that setTimeout is an asynchronous function, so your code doesn't wait for it to finish before looping again. To get around this you have to create your new timer inside the previous timer.
Likewise you have to call any actions you want to execute from inside the timer and can't just call them from in the while loop, because they won't wait for the timer to finish.
function logFun() {
console.log("%%--Hi--%%");
// execute actions
setTimeout(logFun, 5000);
}
This is what yibuyisheng has done with his answer that just showed up. (Still posting because the answer was not explained.)
Alternatively, if you must create the setTimeout() from the while loop, you could have a boolean (true/false) lock it. This is not as clean as yibuyisheng's answer, but it also allows you to add as much logic as you'd like to control enabling and disabling the timeout.
Example:
window.isTimeoutLocked = false;
while(true) {
if (!window.isTimeoutLocked) {
var myFunction = function () {
console.log("%%--Hi--%%");
//The timeout has fired. Unlock it for the next one.
window.isTimeoutLocked = false;
}
window.setTimeout(myFunction, 5000);
//Timeout is queued. Lock this code until the timeout fires.
window.isTimeoutLocked = true;
}
}
Also, I doubt that an infinite while loop is best for your upstream code. There is probably a callback that you can hook into, like requestAnimationFrame or some relevant event.
I have this function:
isAuthenticated = (): boolean => {
xxx
};
I am using AngularJS and I would like to know how can I make a function such as
keepCheckingAuthentication()
That will call the is Authenticated() function every 60 seconds?
There’s a setInterval function that will call any code with given time interval in ms:
var intervalID = setInterval(function() { console.log('Works!') }, 1000);
Later you can cancel the timer using clearInterval(intervalID).
If isAuthenticated can be modified to actually make a request to call the server in order to check authentication, and can return a promise that resolves or rejects when this is done, then I would do something like
var keepCheckingAuthentication = function() {
return isAuthenticated().catch(angular.noop).then(function(isAuth) {
// Can do something different if isAuth == false
return $timeout(keepCheckingAuthentication, 60 * 1000);
});
});
Note the call to catch. This effectively converts any rejections to a success, so the next then callback runs in every case.
Using something like this rather than $setInterval means there will always be 60 seconds between responses from the server, rather than requests made. On a slower connection, or an overloaded server, this means there is a lower chance of adding to the overloaded connection or server, as you're sure the previous request has finished before sending off another one.
you can probably use $interval function (wrapper of window.setInterval() in AngularJS)?
The documentation of $interval function is here
In your case keepCheckingAuthentication() is the function and you can adjust the other parameters accoding to your needs? Does this help?
example:
$interval(myFunctionAtInterval, 5000) // Scheduled for every 5 seconds, for instance
funtion myFunctionAtInterval() {...}
I tend to avoid setInterval whenever I can, i.e. always (Paul Irish talks about this in this video).
What I do is wrap a setTimeout in a function that recursively calls itself (with a condition that allows me to easily stop, or to let the data decide when it's not needed anymore).
var condition = true;
$scope.count = 1;
function myFunc(){
$scope.count += 1;
}
var timer = function(){
myFunc();
if( condition ){
$timeout(timer, 1000);
}
};
timer();
I am using angular built in $timeout here as it's always suggested.
A demo
use $interval.this code will help you:
var callefunc=function() {
console.log('hey i am calle');
}
$scope.caller=function(){
var stop = $interval(callefunc, 1000);
}
here you can call a caller function when you want to start function callefunc on interval of 1 second .
I have a page that I want to update non stop, every few seconds.
For this, I wrote the following:
var to;
$(function () {
to = setTimeout(updateDivContent, 2000);
});
function updateDivContent() {
$('#topbox').load('/home/blabla', null);
$('#leftgraph').load('/home/blabla', null, function () {
to = setTimeout(updateDivContent, 2000);
});
};
This worked, however, it leads to what I presume is a memory leak as after around 15 minutes, the computer almost freezes up with the browser taking up all available memory and CPU.
I am guessing that the Timeout is basically stacking, but, I am not sure how to fix this. I have tried getting rid of the second timeout and putting the first one inside a while(true) loop, but, I just couldn't get it to work.
Can anyone suggest anything?
This looks fine actually. But if the first Ajax call does not finish within two seconds, it will stack, and this could (don't know for sure) cause problems.
The timeout itself does not stack, since you are initiating a new one only after the previous one finished.
Try to initiate a new timeout once both Ajax requests finished:
$.when($('#topbox').load('/home/blabla'),
$('#leftgraph').load('/home/blabla')
).then(function () {
setTimeout(updateDivContent, 2000);
});
Reference: $.when
I think it is better to use setInterval instead of setTimeOut.
See this post.
You probably want to call clearTimeout to invalidate the previous timer, like this:
clearTimeout(to);
to = setTimeout(updateDivContent, 2000);
can you this it will call ever 2 second
to = setInterval("updateDivContent", 2000);
function updateDivContent() {
$('#topbox').load('/home/blabla', null);
$('#leftgraph').load('/home/blabla', null, function () {
//to = setTimeout(updateDivContent, 2000);
});
};
Try setInterval:
var to;
$(function () {
to = setInterval(updateDivContent, 2000);
});
function updateDivContent() {
$('#topbox').load('/home/blabla', null);
$('#leftgraph').load('/home/blabla')
};
I have the following code:
// After 8 seconds change the slide...
var timeout = setTimeout("changeSlide()", 8000);
$('div.slideshow').mouseover(function() {
// If the user hovers the slideshow then reset the setTimeout
clearTimeout(timeout);
});
$('div.slideshow').mouseleave(function() {
clearTimeout(timeout);
var timeout = setTimeout("changeSlide()", 8000);
});
What I want to happen is make the function changeSlide run EVERY 8 seconds in a loop unless someone hovers the slideshow div. When they remove the cursor then do the timeout again!
However the loop only happens once and the hover doesn't stop the timeout or start it again :/
EDIT:
This loops great but the hover on and off causes the function to run multiple times:
// After 8 seconds change the slide...
var timeout = setInterval(changeSlide, 2000);
$('div.slide').mouseover(function() {
// If the user hovers the slideshow then reset the setTimeout
clearInterval(timeout);
});
$('div.slide').mouseleave(function() {
clearInterval(timeout);
var timeout = setInterval(changeSlide, 2000);
});
You have a couple issues here. First off, when you set a timeout, you need to store the return of that function call into a variable if you potentially want to stop it.
var slide_timer = setTimeout(changeSlide, 8000);
Second, when you call clearTimeout (rather than clearInterval), you need to pass it an argument. What argument? That variable you stored when you called setTimeout
clearTimeout(slide_timer);
Third, when you use setTimeout, it only fires once. setInterval will continue to fire, then you'd use clearInterval to stop it.
There is an issue in timing with using intervals rather than timeouts. The browser treats them subtly differently, and it may be important to your code to know the difference and use the proper method. If you use intervals, since they only fire once, you'll have to re-establish the timeout every time it fires.
var slide_timer = setTimeout(function () {
changeSlide();
var slide_timer = setTimeout(changeSlide, 8000);
}, 8000);
OR
var slide_timer = setTimeout(changeSlide, 8000);
...
function changeSlide() {
... your code ...
var slide_timer = setTimeout(changeSlide, 8000);
}
(I prefer the former method)
And lastly, whether you use timeouts or intervals, don't pass a string to setTimeout, pass a function reference. See the sample code above, or like this:
var slide_timer = setTimeout("changeSlide()", 8000); // <--- DON'T
var slide_timer = setTimeout(changeSlide, 8000); // <--- DO
var slide_timer = setTimeout(function () { // <--- DO
changeSlide() ;
// other script
}, 8000);
Putting it all together:
// After 8 seconds change the slide...
var slide_timer = setTimeout(changeSlide, 8000);
$('div.slideshow').hover(function() {
// If the user hovers the slideshow then reset the setTimeout
clearTimeout(slide_timer);
}, function() {
slide_timer = setInterval(changeSlide, 8000);
});
Documentation
clearTimeout - https://developer.mozilla.org/en/DOM/window.clearTimeout
setTimeout - https://developer.mozilla.org/en/DOM/window.setTimeout
clearInterval - https://developer.mozilla.org/en/DOM/window.clearInterval
setInterval - https://developer.mozilla.org/en/DOM/window.setInterval
SO answer discussing the subtle difference between intervals and timeouts - https://stackoverflow.com/a/7900293/610573
When you specify setTimeout (or setInterval), it returns a value that is then used for clearTimeout and clearInterval. Correct usage is as follows:
var timeout = setTimeout(changeSlide, 8000);
clearTimeout(timeout);
Also note I am using clearTimeout, not clearInterval.
You'll also notice that I did not put quotes around 'changeSlide', and that I dropped the parens. When passing a string to setTimeout, eval() is used. eval() is, in general, recommended to be avoided. So, instead, we pass it the direct reference to the function (without quotes). We do not use parens, because that would actually call changeSlide() right away, instead of deferring execution to setTimeout (and would pass, as an argument to setTimeout, the result of changeSlide())
EDIT: To get it to run continously, you have to call setTimeout again after each changeSlide call. setTimeout runs once. As an alternative, you can use setInterval, which automatically repeats. The one caveat to setInterval is that if the interval is too short and the callback it calls takes a long time to run, you can end up with a bunch of intervals queued up to execute one after another, without delay. An 8 second interval would likely not face this problem.
EDIT 2:
var timeout;
var changeSlide = function(){
// do something to change slides
clearTimeout(timeout);
timeout = setTimeout(changeSlide, 8000);
}
// queue up the first changeSlide, all others happen inside changeSlide
timeout = setTimeout(changeSlide, 8000);
$('div.slideshow').mouseleave(function() {
clearTimeout(timeout);
var timeout = setTimeout(changeSlide, 8000);
});
I think you need setInterval and not setTimeout, since:
setTimeout(expression, timeout); runs the code/function once after the timeout
setInterval(expression, timeout); runs the code/function in intervals, with the length of the timeout between them
In the end this worked the best (but I won't accept this as my answer as it was others who helped me get to this point)
// After 8 seconds change the slide...
var slide_timer = setInterval(changeSlide, 2000);
$('div.slideshow').hover(function() {
// If the user hovers the slideshow then reset the setTimeout
clearInterval(slide_timer);
}, function() {
slide_timer = setInterval(changeSlide, 2000);
});
Your issue may be the mouseover event. The mouseover event bubbles, so if you have a nested HTML structure, then the event may be called more than once. If you are using jQuery, you should use the mousenter event, which will only get called once for the element.
On a different note, instead of using setInterval use a setTimeout pattern. Something like this:
//Immediately Invoked Function Expression that gets called immediately
(function() {
//Make the initial call to your setTimeout function
repeat();
//Function will constantly be called
function repeat() {
setTimeout(function() {
//(Put your conditional logic here)
console.log('test');
repeat();
}, 2000);
}
})();