setTimeout continuous loop without wait - javascript

I'm trying to get setTimeout to re-run the function it's inside after 15 seconds, it's not waiting 15 seconds and just doing it in a constant loop.
Here's my current code
function checkSession(x) {
http.abort();
http.open("GET", siteURL+"processes/ajax.php?call=check_session&string="+x+"&new="+Math.random(), true);
http.onreadystatechange = function() {
if(http.readyState == 4) {
if(http.responseText == true) {
updateSession(x);
} else {
setTimeout(checkSession(x),15000);
}
}
}
http.send(null);
}
I don't see any problems in the code itself, the only thing wrong is that it's just doing a constant loop without waiting the "15000" miliseconds.

change the setTimeout call to:
setTimeout(function(){checkSession(x)},15000);
As you have it now, checkSession is called immediately and then passed as an argument to setTimeout. Wrapping it inside the function allows for the call to be deferred.

Your explanation:
The function is like this: setTimeout( function, delay );
Your method call was not setting an anonymous function or reference to a function as the function argument.
Wrong: setTimeout(checkSession(x),15000);
Reason: checkSession(x) is a function call, not a reference to a function or anonymous function
Right: setTimeout(function() {checkSession(x) },15000);
Reason: the function call is now wrapped as an anonymous function in place and the function argument is set for the setTimeout( function, delay ) method.
Hope that helps to clear it up for you!

Related

How setTimeout works?

I have a concern with setTimeout function in javascript. when we call setTimeout function without return anything, it is okay for me. like
setTimeout(function() {
console.log("ok function called")
},2000);
here in the above example it just simply call that function after 2000ms,
And if I write this like
setTimeout(function(params) {
console.log("passed value is"+params)
},2000,55);
now it will call this function with 55 as an argument, right?
But problem is that when I call to write this like
setTimeout(function(params) {
console.log("passed value is"+params)
}(55),2000);
here function is calling with 55 as params but it is now waiting for 2000ms
And when I wrote like
setTimeout(function(params) {
console.log("passed value is "+params);
return function(){
console.log(params)
};
}(55),2000);
in this only return function is calling with 2000ms delay, the line console.log("passed value is "+params); is executing instantly
please help me get out of this problem.
One is a function. Another is a function call.
First, let's forget javascript for now. If you know any other programming language, what do you expect the two pieces of code below to do?
function a () { return 1 }
x = a;
y = a();
What do you expect x to be? 1 or a pointer to function a?
What do you expect y to be? 1 or a pointer to function a?
A function is not a function call. When you call a function it returns a value.
Now let's switch back to javascript. Whenever I get confused by a piece of code, I try to make the syntax simpler so that I can understand what's going on:
setTimeout(function() {console.log("ok function called")}, 2000);
Now, that's a compact piece of code, let's make the syntax simpler. The above code is the same as:
var a = function() {console.log("ok function called")};
setTimeout(a, 2000);
So what does that do? It will call the function a after 2 seconds.
Now let's take a look at:
setTimeout(function() {console.log("ok function called")}(), 2000);
// Note this ----------^^
That's the same as:
var b = function() {console.log("ok function called")}();
setTimeout(b, 2000);
which can further be simplified to:
var a = function() {console.log("ok function called")};
var b = a();
setTimeout(b, 2000);
So I hope you see what you're really passing to setTimeout. You're passing the return value of the function, not the function.
When you write
setTimeout(function (params) { return something; }(55), 2000);
what actually happens is something like this:
var _temp_func = function (params) { return something; };
var _temp = _temp_func(55);
setTimeout(_temp, 2000);
The anonymous function you have as a parameter to setTimeout is evaluated immediately, even before the call to setTimeout itself. In contrast to that, the actual parameter that ends up in _temp here is called with a delay. This is what happens in your last example.
setTimeout takes only function name without parenthesis.
correct syntax : setTimeout(Helloworld) - here you are setting function
incorrect syntax : setTimeout(HelloWorld()) - here you are calling function
or non IIFE function.
It's an IIFE that you are passing hence it is getting called immediately.
setTimeout(function (params) { return something; }(55), 2000);

Jquery setTimeout not working if used without alert

I am implementing this code.
$('.mcqtd').click(function(){
var choice = this.id;
checkanswer(choice,questions[x].correctAnswer);
window.setTimeout(showquestion(x+1,0),3000); // 1 seconds
});
}
function checkanswer(answer,original){
if (answer=='choice'+original){
$('#choice'+original).css('backgroundColor', '#DD792E');
$('#choice'+original).append("<span class='padding10 mcqsymbol'><img src='images/right_icon.png' /></span>");
} else {
$('#'+answer).css('backgroundColor', '#AFA689');
$('#'+answer).append("<span class='padding10 mcqsymbol'><img src='images/wrong_icon.png' /></span>");
$('#choice'+original).css('backgroundColor', '#DD792E');
$('#choice'+original).append("<span class='padding10 mcqsymbol'><img src='images/right_icon.png' /></span>");
}
}
Onclick, the tds should be highlighted, and after 3 seconds, the next question should be loaded but this is not happening, after 3 seconds the next question is being loaded, but backgrounds are not changing. If I alert something inside checkanswer(), the code works. Any ideas what should I do?
The to executing part must be wrapped in a anonymous function if you want to use parametes. Otherwise it is not working in setTimeout.
setTimeout(function() {
showquestion(x + 1, 0);
}, 3000);
As A.Wolff noted in the comments below, you can even pass parameters to a called function in setTimeout by extening the parameters behind the time.
// note there are no '()' behind the function name
setTimeout(showquestion, 3000, x + 1, 0);
If you would call a function without parameters you can left out the wrapper function and the additional parameters too.
// note there are no '()' behind the function name
setTimeout(functionWithoutParameter, 3000);
What you do is calling the function directly and passing it's return value over to setTimeout. As you intend to use arguments with this, you will have to make use of an anonymous function, eg:
setTimeout(function(){ showquestion(x+1, 0);}, 3000);
Edit:
If you only have a functioncall without arguments it woulf look like:
setTimeout("foo()", 3000);
or
setTimeout(foo, 3000);
Dirtly call this in setTimeout method its not working.
setTimeout(question, 3000);
function question() {
showquestion(x + 1, 0)
}

Using clearInterval within a function to clear a setInterval on another function

I think im missing something fairly obvious with how the clearInterval method works.
So with the code below. I would expect the first function call to execute testFunction and set the interval to repeat the function. The 2nd call would execute the second function which will remove the interval from the 1st function. As this would execute far before the 5000ms interval the first function would not be executed again. However it does not behave like this.
Could someone please explain what is wrong with my method?
Reason for this is in a program I am writing I am making repeated get requests, every 30 seconds or so , using setTimeout but i would like a method to easily remove this interval at other points in the program
function testFunction() {
$("#test").append("test");
setTimeout(testFunction, 5000);
}
function stopFunction() {
clearTimeout(testFunction);
}
testFunction();
stopFunction();
setTimeout returns an ID so you should
var timeoutID = setTimeout(blah blah);
clearTimeout(timeoutID);
setTimeout returns an object that you need to pass into the clearTimeout method. See this article for an example: http://www.w3schools.com/jsref/met_win_cleartimeout.asp
setTimeout returns an identifier for the timer. Store this in a variable like:
var timeout;
function testFunction(){
...
timeout = setTimeout(testFunction, 5000);
}
function stopFunction(){
clearTimeout(timeout);
}
Here is a simple and I think better implementation for this .
var _timer = null,
_interval = 5000,
inProgress = false,
failures = 0,
MAX_FAILURES = 3;
function _update() {
// do request here, call _onResolve if no errors , and _onReject if errors
}
function _start() {
inProgress = true;
_update();
_timer = setInterval(_update, _interval);
}
function _end() {
inProgress = false;
clearInterval(_timer);
}
function _onReject(err) {
if (failures >= MAX_FAILURES) {
_end();
return false;
}
_end();
failures++;
_start();
}
function _onResolve(response) {
return true;
}

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)

Return true and setimout

Why doesn't this function return true?
function test(str) {
window.setTimeout(function() {
if(str == 'ok') {
return true;
}
}, 1000);
}
console.log(test('ok'));
That's not exactly what i want to do.
I have a function nammed test() who does some actions after 1 second.
I want to execute next function, when test() is finished (so after the timeout).
How i can know when test i finished ?
Tracing your code, here's what happens.
test() is invoked.
setTimeout schedules a function to be called 1000 ms later.
test() concludes execution, no return statement was executed, so undefined is returned instead.
about 1000 ms later the scheduled function fires.
The scheduled function returns true to nothing.
In other words, it just doesn't work that way. The JS interpreter does not pause, it continues over the timeout. You cannot pause execution in JS.
Instead you typically use callbacks:
function test(str, callback) {
window.setTimeout(function() {
if (str === 'ok') {
callback(true);
}
}, 1000);
}
// logs 'true' 1000 ms later
test('ok', function(result) {
console.log(result);
});
// logs nothing, callback never fires
test('NOTOK!', function(result) {
console.log(result);
});
This code will do more what you seem to have expected.
It does not return true because the setTimeout call is asynchronous. Also, the return value true in your code comes from an inner function.
The normal way of handling such program flow is to pass a callback to the asynchronous function.
function test(str, callback) {
window.setTimeout(function() {
callback(str == 'ok');
}, 1000);
}
test('ok', function (result) {
console.log(result);
});
The function passed as the second argument to test() will be called when setTimeout executes the code. The argument to the callback function will tell if str is was ok or not.
For starters, settimeout is an asynchronous method, so the actual function test() will have finished and returned before the settimout code runs.
Secondly however, you are only returning true from the settimeout function not the test function, so you will never get anything other than false.
It doesn't return true because asynchronous function setTimeout() will execute after 1000 ms and console.log will execute in normal fashion without waiting of your 'test' function.

Categories

Resources