SetTimeout not functioning properly - javascript

This code is running all 21 console logs all at once. It should, however, run them one at a time at a set interval Any suggestions?
var index = 1;
var switchBG = function(num){
if( num < 22 ){
console.log('index' + index);
console.log('num' + num);
index++;
function_timer(index);
}
};
var timer;
var function_timer = function(index){
clearTimeout(timer);
timer = setTimeout(switchBG(index), 10000);
};

You need to pass a function as an argument to setTimeout. Try this:
timer = setTimeout(function() {
switchBG(index);
}, 10000);
Doing setTimeout(switchBG(index), 10000); basically evaluates switchBG(index) and passes its return value (which is currently undefined) to setTimeout.

When you do:
setTimeout(switchBG(index), 10000);
you are calling switchBG(index) immediately, and then passing it's return value (which is undefined) to setTimeout. Instead you want to pass a function reference, and then pass the additional arguments to setTimeout:
setTimeout(switchBG, 10000, index);
If you want to use additional arguments to setTimeout like that to work in Internet Explorer, you'll need to shim it. It will work in every other browser without a shim.
If you want to support IE and don't want to use the shim, you can create an extra anonymous function to achieve the same result:
setTimeout(function(){ switchBG(index); }, 10000);

Related

How do i make a javascript fuction repeat every few seconds? [duplicate]

I want repeat this code every 4 seconds, how i can do it with javascript or jquery easly ? Thanks. :)
$.get("request2.php", function(vystup){
if (vystup !== ""){
$("#prompt").html(vystup);
$("#prompt").animate({"top": "+=25px"}, 500).delay(2000).animate({"top": "-=25px"}, 500).delay(500).html("");
}
});
Use setInterval function
setInterval( fn , miliseconds )
From MDC docs:
Summary
Calls a function repeatedly, with a fixed time delay between each call to that function.
Syntax
var intervalID = window.setInterval(func, delay[, param1, param2, ...]);
var intervalID = window.setInterval(code, delay);
where
intervalID is a unique interval ID you can pass to clearInterval().
func is the function you want to be called repeatedly.
code in the alternate syntax, is a string of code you want to be executed repeatedly. (Using this syntax is not recommended for the same reasons as using eval())
delay is the number of milliseconds (thousandths of a second) that the setInterval() function should wait before each call to func. As with setTimeout, there is a minimum delay enforced.
Note that passing additional parameters to the function in the first syntax does not work in Internet Explorer.
Example
// alerts "Hey" every second
setInterval(function() { alert("Hey"); }, 1000);
setInterval(function(){
// your code...
}, 4000);
It's not too hard in javascript.
// declare your variable for the setInterval so that you can clear it later
var myInterval;
// set your interval
myInterval = setInterval(whichFunction,4000);
whichFunction{
// function code goes here
}
// this code clears your interval (myInterval)
window.clearInterval(myInterval);
Hope this helps!
Another possibility is to use setTimeout, but place it along with your code in a function that gets called recursively in the callback to the $.get() request.
This will ensure that the requests are a minimum of 4 seconds apart since the next request will not begin until the previous response was received.
// v--------place your code in a function
function get_request() {
$.get("request2.php", function(vystup){
if (vystup !== ""){
$("#prompt").html(vystup)
.animate({"top": "+=25px"}, 500)
.delay(2000)
.animate({"top": "-=25px"}, 500)
.delay(500)
.html("");
}
setTimeout( get_request, 4000 ); // <-- when you ge a response, call it
// again after a 4 second delay
});
}
get_request(); // <-- start it off
const milliseconds = 4000
setInterval(
() => {
// self executing repeated code below
}, milliseconds);
Call a Javascript function every 2 second continuously for 20 second.
var intervalPromise;
$scope.startTimer = function(fn, delay, timeoutTime) {
intervalPromise = $interval(function() {
fn();
var currentTime = new Date().getTime() - $scope.startTime;
if (currentTime > timeoutTime){
$interval.cancel(intervalPromise);
}
}, delay);
};
$scope.startTimer(hello, 2000, 10000);
hello(){
console.log("hello");
}

What is wrong with this Javascript script?

I'm writing a simple timer this way:
function timer(init){
console.log(init);
setTimeout(function(init){
timer(init+1);
},1000);
}
timer(1);
It's a recursive function (Note: I am aware it is an infinite loop, just not important now). However as simple as it seems, it fails as the output of each interval is NaN, and not an increased number as expected.
The function is so simple that I cannot figure out what the issue is. What am I missing?
The problem here is that you are overriding the value of init by passing an argument to setTimeout's callback function.
function timer(init) {
console.log(init);
setTimeout(function() {
timer(init+1);
},1000);
}
timer(1);
This way the init value is the one you passed into the timer call.
The function body you're passing in to setTimeout is a callback function, no arguments are passed to it (because setTimeout doesn't pass any).
function timer(init) {
console.log(init);
setTimeout(function() {
timer(init + 1);
}, 1000);
}
timer(1);
The simplest way to do it would be something like this:
var t = 0;
function timer() {
console.log(++t);
setTimeout(timer, 1000);
}
timer();
You need to feed an anonymous function as a parameter instead of a string, the latter method shouldn't even work per the ECMAScript specification but browsers are just lenient.
setTimeout(function() {
timer(init+1);
}, 1000)

setInterval(setTimeout) function for given invokes javascript

I need to invoke some function given number of times through given delays. How should I do - declare variable for timer and pass it to invoking function for stopping timer in some moment or in loop (n times) invoke setTimeout once ( or some another approach to skeep delay time once) or other.Thanks.
edit to fix syntax eror
var timerID = null;
var n = 5;
this.timerID = setInterval(function(){
funcToInvoke(n,timerID){
if(invokeNumber == n){
clearInterval(timerID);
return;
}
else { do something}
}
},delay)
Yes, the approach is common and better than calling setTimeout in a loop (with a fixed number of times). It is more performant than that and also more flexible, because the interval will be stopped dynamically (might check for a future condition).
However, your code is a bit messy. Fixed:
// Assuming we a have
// n
// delay
// funcToInvoke
// and execute in context of some object
var that = this,
numberOfInvokes = 0;
this.timer = setInterval(function() {
// "this" points to the global object
if (numberOfInvokes == n)
clearInterval(that.timer);
else
funcToInvoke(numberOfInvokes);
numberOfInvokes++;
}, delay);
Your current method has a syntax problem, you can't have a function parameter like this.timerID). In fact, you should remove the whole funcToInvoke declaration, and declare n and timerID as local variables, so they will be available to the closure. Like this:
// Don't forget to define n here!
var n = 5;
// Change timerID to local var instead of property
var timerID = null;
timerID = setInterval(function(){
if(invokeNumber == n){
clearInterval(timerID);
return;
} else {
//do something
}
// You can setTimeout again anywhere in this function if needed
}, delay);
If you want an approximate delay, setInterval is probably ok. If you want a more precise interval, then repeated calls to setTimeout are better as you can adjust the length of time to the next call based on the time since the last call.
E.g. for a clock ticking every second, you can do repeated calls to setTimeout, setting the lag to just after the next full second.

Javascript function call into loop each time

I have function called rotator(id): this function animate div and I can called this function with different id for animate different elements
Actually I use 5 differents id , 1,2,3,4,5
And for call I need put :
rotador(1);rotador(2);rotador(3);rotador(4);rotador(5);
The problem it´s that I want to rotate in automatic mode. For this I think to use this
for (i=0;i<=5;i++) {
setTimeout(rotador(i),2000);
}
But it doesn't work because it animates all in the same time, no let firt execute the first and continue before of first go second , etc , etc and when go the end or number 5 start other time in one
My problem it´s this if you can help me THANKS !!! :) Regards
You are actually calling the rodator(i) function, and schedule for execution after 2 seconds the result of the rodator. In other words, your code is now equalent to:
for (i=0;i<=5;i++) {
var result = rotador(i);
setTimeout(result,2000);
}
You can accomplish this either by creating a function for the callback:
for (i=0;i<=5;i++) {
setTimeout((function(i){
return function(){
rotador(i);
}
})(i),2000 * i);
}
or you can call the next rodator in the rotador function itself:
var rotador = function(i){
// your code
if (i < 5) {
setTimeout(function(){rotaror(i + 1);}, 2000);
}
}
Note: the closure in the second example is needed to call the function with the correct value of i. We are creating an anonymous function, and create i as a local scope variable, which value won't be mutated by the outerscope changes. (we can rename i to n in the local scope, if this would be more readable). Otherwise the value of i will be 5 each time rotador is called, as the value of i would be modified before the actual function call.
since setTimeout() does not wait for the function to be executed before continuing, you have to set the delay to a different value for different items, something like 2000 * (i + 1) instead of just 2000
EDIT: yes, and you need the callback as Darhazer suggests
rotationStep(1);
function rotador(id)
{
console.log(id);
}
function rotationStep( currentId )
{
rotador(currentId);
var nextId = currentId<5 ? currentId+1 : 1;
setTimeout(function(){ rotationStep(nextId) },2000); //anonymous function is a way to pass parameter in IE
}
Use a callback:
setTimeout(function() {
rotador(i)
}, 2000)

how to write a recursive method in JavaScript using window.setTimeout()?

I'm writing a JavaSCript class that has a method that recursively calls itself.
Scheduler.prototype.updateTimer = function () {
document.write( this._currentTime );
this._currentTime -= 1000;
// recursively calls itself
this._updateUITimerHandler = window.setTimeout( arguments.callee , 1000 );
}
Property description:
_currentTime: the currentTime of the timer in miliseconds.
_updateUITimerHandler: stores the reference so can be used later with clearTimeout().
my problem is where I'm using recursion with setTimeout(). I know setTimeout() will accept some string to execute, or a reference to a function. since this function is method of an object, I don't know how to call it from outside. so I used the second format of setTimeout() and passed in a reference to the method itself. but it does not work.
Try this:-
Scheduler.prototype.startTimer = function() {
var self = this;
function updateTimer() {
this._currentTime -= 1000;
self.hTimer = window.setTimeout(updateTimer, 1000)
self.tick()
}
this.hTimer = window.setTimeout(updateTimer, 1000)
}
Scheduler.prototype.stopTimer = function() {
if (this.hTimer != null) window.clearTimeout(this.hTimer)
this.hTimer = null;
}
Scheduler.prototype.tick = function() {
//Do stuff on timer update
}
Well the first thing to say is that if you're calling setTimeout but not changing the interval, you should be using setInterval.
edit (update from comment): you can keep a reference from the closure if used as a class and setInterval/clearInterval don't require re-referencing.
edit2: it's been pointed out that you wrote callee which will work quite correctly and 100% unambiguously.
Out of completeness, this works:
function f()
{
alert('foo');
window.setTimeout(arguments.callee,5000);
}
f();
so I tried out document.write instead of alert and that is what appears to be the problem. doc.write is fraught with problems like this because of opening and closing the DOM for writing, so perhaps what you needed is to change the innerHTML of your target rather than doc.write
You could hold a pointer towards it...
/* ... */
var func = arguments.callee;
this._updateUITimerHandler = window.setTimeout(function() { func(); }, 1000);
/* ... */

Categories

Resources