How does setTimeout work? [duplicate] - javascript

This question already has answers here:
Calling functions with setTimeout()
(6 answers)
Closed 6 years ago.
-so i am obviously trying to get two functions to run automatically whilst on a timer using setTimeout. However i am not to sure how it works. All i can see when i search it up is it in a function. so how do i have it outside a function?
function ChangeImage() {
if(position < TrafficL.length) {
document.getElementById("myImage").src = TrafficL[position];
position++
}
}
function RestartPos() {
if (position==3)
document.getElementById("myImage").src = TrafficL["position"]
position=0
var setTimeout = (ChangeImage(),1500)
var setTimeout = (RestartPos(),6000)

You sould call setTimeout as a function:
setTimeout(ChangeImage,1500);
setTimeout(RestartPos,6000);
ChangeImage and RestartPos are like variables referencing a function. If you place parentheses behind them means, you are calling them immediately, but you want to call them after a given time.
You can store the value return by setTimeout() in a variable though, but it's only for cancelling the countdown later:
// nothing happens, because the timeout was cancelled in 1.5s
var t = setTimeout(ChangeImage,1500);
clearTimeout(t);

Related

Javascript code doesn't work as expected [duplicate]

This question already has answers here:
setTimeout calls function immediately instead of after delay
(2 answers)
Closed 6 years ago.
I have a recursive SetTimeout function that clicks a filter on my page after the filters have loaded (they're loaded through Ajax, so not available immediately on page load).
$scope.clickFilter = function () {
var filter = $('.filter-item')
.find('input[value="' + $scope.activeFilter + '"]');
if (filter.length < 1) {
setTimeout($scope.clickFilter(), 1000);
} else {
$(filter).trigger("click");
}
}
However, when the filters take a long time to load, I get "Uncaught RangeError: Maximum call stack size exceeded(…)"
How do I prevent this and make sure it runs until completion?
The problem is here:
setTimeout($scope.clickFilter(), 1000);
Putting () after the function reference means that you want the function to be called, immediately, at that point in the code. What you probably want instead is something like:
setTimeout($scope.clickFilter.bind($scope), 1000);
which will
pass a function reference to setTimeout(), as is required, and
ensure that the function will be invoked with the proper this value (what the .bind() part does)
Once you get it working, the term "recursive" isn't really appropriate. Yes, the function is referencing itself when it arranges for the call after the timer expires, but it's not directly calling itself; it's asking something else (the timer mechanism) to call it later.

calling multiple setInterval() functions in js with a loop [duplicate]

This question already has answers here:
setTimeout in for-loop does not print consecutive values [duplicate]
(10 answers)
Closed 5 years ago.
I'm new to javascript and I'm having trouble using the setInterval() function properly.
Basically I want to call a function at different given intervals for different parameters both of which I have in lists.
I have a function called myfunction. I have a list called myparam with all of the variables I want to pass this function. And finally I have a list called myfrequency which is the time in millis that I want between each call of myfunction with the parameter given in myparam. I'm trying something like this but it's not working:
for(i=0;i<myparam.length();i++;){
setInterval(function(){myfunction(myparam[i]);},myfrequency[i]);
}
The result of the above code is that it works only for the last index. myfunction gets called at the correct interval with the correct parameter for ONLY the last value in myparam.
Why does this happen? Is my thinking that setInterval() sets up the calling of a function at an interval incorrect?
Well it's because setInterval has a delay which means when the interval runs
the loop is already been finish
To do that just create another function which will start your interval
function StartInterval(index, frequency) {
setInterval(function(){
myfunction(index);
},frequency);
}
Then inside your loop just call this function and pass something
for(i=0;i<myparam.length;i++){
StartInterval(myparam[i], myfrequency[i])
}
/** set what value you want **/
var myparam = [10,20,30];
var myfrequency = [1000,2000,3000];
function myfunction(index) {
console.log(index);
}
function StartInterval(index, frequency) {
setInterval(function(){
myfunction(index);
},frequency);
}
for(i=0;i<myparam.length;i++){
StartInterval(myparam[i], myfrequency[i])
}

Why does html onclick runs when it added by javascript [duplicate]

This question already has answers here:
setTimeout calls function immediately instead of after delay
(2 answers)
Closed 6 years ago.
I have a recursive SetTimeout function that clicks a filter on my page after the filters have loaded (they're loaded through Ajax, so not available immediately on page load).
$scope.clickFilter = function () {
var filter = $('.filter-item')
.find('input[value="' + $scope.activeFilter + '"]');
if (filter.length < 1) {
setTimeout($scope.clickFilter(), 1000);
} else {
$(filter).trigger("click");
}
}
However, when the filters take a long time to load, I get "Uncaught RangeError: Maximum call stack size exceeded(…)"
How do I prevent this and make sure it runs until completion?
The problem is here:
setTimeout($scope.clickFilter(), 1000);
Putting () after the function reference means that you want the function to be called, immediately, at that point in the code. What you probably want instead is something like:
setTimeout($scope.clickFilter.bind($scope), 1000);
which will
pass a function reference to setTimeout(), as is required, and
ensure that the function will be invoked with the proper this value (what the .bind() part does)
Once you get it working, the term "recursive" isn't really appropriate. Yes, the function is referencing itself when it arranges for the call after the timer expires, but it's not directly calling itself; it's asking something else (the timer mechanism) to call it later.

Maximum call stack size exceeded on SetTimeout recursive function (Javascript) [duplicate]

This question already has answers here:
setTimeout calls function immediately instead of after delay
(2 answers)
Closed 6 years ago.
I have a recursive SetTimeout function that clicks a filter on my page after the filters have loaded (they're loaded through Ajax, so not available immediately on page load).
$scope.clickFilter = function () {
var filter = $('.filter-item')
.find('input[value="' + $scope.activeFilter + '"]');
if (filter.length < 1) {
setTimeout($scope.clickFilter(), 1000);
} else {
$(filter).trigger("click");
}
}
However, when the filters take a long time to load, I get "Uncaught RangeError: Maximum call stack size exceeded(…)"
How do I prevent this and make sure it runs until completion?
The problem is here:
setTimeout($scope.clickFilter(), 1000);
Putting () after the function reference means that you want the function to be called, immediately, at that point in the code. What you probably want instead is something like:
setTimeout($scope.clickFilter.bind($scope), 1000);
which will
pass a function reference to setTimeout(), as is required, and
ensure that the function will be invoked with the proper this value (what the .bind() part does)
Once you get it working, the term "recursive" isn't really appropriate. Yes, the function is referencing itself when it arranges for the call after the timer expires, but it's not directly calling itself; it's asking something else (the timer mechanism) to call it later.

setTimeout not working in NodeJS [duplicate]

This question already has answers here:
Why is setTimeout executing immediately? [duplicate]
(4 answers)
Closed 8 years ago.
I have this slideUp function that calls the animate function. The objective is to make a div appear to
slide up on the screen by recalling the animate function every 20ms, and rerendering the div in the browser after adjusting the css for the div position.
I'm using Node js, and due to the
asynchronous behaviour, I believe that the timeout only gets involked once, and that the program continues running while it waits on the timeout to complete.
When i print the value of 'bottom' to the console, it has looped through 20 times as expected. Only the final view
gets rendered thou. Can anyone offer any way to get around this problem so that it rerenders each of the 20 times?
slideUp: function () {
var bottom=0;
this.animate(bottom);
},
animate: function(bottom){
bottom++;
if (bottom<20){
this.view.getClientNotificationElement().setAttribute("style","margin-bottom:"+bottom+"px");
this.clientNotification.attachTo(this.view.getClientNotificationElement());
setTimeout(this.animate(bottom), 20);
console.log(bottom);
}
}
You are passing the return value of this.animate(bottom) to setTimeout.
The animate function doesn't have a return statement, so it returns undefined.
The effects of the function happen immediately (because you are calling it) and then setTimeout does nothing.
Pass a function to setTimeout instead.
var self = this;
var callback = function () {
self.animate(bottom);
};
setTimeout(callback, 20);

Categories

Resources