I have a piece of code with while loop which I would like to stop by setTimeout(). But it seems like a endless loop, which never triggers setTimeout(). If I remove while loop, timeout triggers correctly. What is wrong please?
$(document).ready(function()
{
var i = 0, s = false;
setTimeout( function()
{
s = true;
console.log( "Timeuot!!!" );
console.log( "s value is " + s );
}, 1000 );
while( s === false )
{
console.log( "this is while and s is " + s );
i++;
}
console.log( "iterations: " + i );
});
I have a piece of code with while loop which I would like to stop by setTimeout(). But it seems like a endless loop, which never triggers setTimeout(). If I remove while loop, timeout triggers correctly. What is wrong please?
$(document).ready(function()
{
var i = 0, s = false;
setTimeout( function()
{
s = true;
console.log( "Timeuot!!!" );
console.log( "s value is " + s );
}, 1000 );
while( s === false )
{
console.log( "this is while and s is " + s );
i++;
}
console.log( "iterations: " + i );
});
Share
Improve this question
edited Oct 13, 2016 at 23:02
Čamo
asked Oct 13, 2016 at 11:41
ČamoČamo
4,20218 gold badges79 silver badges144 bronze badges
4
-
@Quentin the
s
inside the setTimeout is set at the global scope. why am I wrong ? – Royi Namir Commented Oct 13, 2016 at 11:46 -
@RoyiNamir — The function passed to
setTimeout
is defined inside another function. It has access to the scope of that function. Since there is a non-globals
in that scope, it accesses thats
. – Quentin Commented Oct 13, 2016 at 11:47 - @RoyiNamir h s inside the setTimeout is the one of the enclosing scope so the one declared and defined a couple of lines above. – pinturic Commented Oct 13, 2016 at 11:48
- @Quentin oh man you're right. my bad. deleting. – Royi Namir Commented Oct 13, 2016 at 11:49
3 Answers
Reset to default 7JavaScript runs a single event loop. It won't stop in the middle of a function to see if there are any events (such as clicks or timeouts) that would trigger a different function.
In short: It won't run the timed function until the while loop has finished.
To do this sort of thing, you'd normally have an event driven iterator.
var i = 0,
s = false;
setTimeout(function() {
s = true;
console.log("Timeuot!!!");
console.log("s value is " + s);
}, 1000);
next();
function next() {
if (s) {
return done();
}
console.log({
s, i
});
i++;
setTimeout(next, 0);
}
function done() {
console.log("iterations: " + i);
}
As already mentioned the while loop blocks the one and only thread. To let your example do the thing you want, replace the while loop with setInterval(function) like this:
$(document).ready(function()
{
var i = 0, s = false;
setTimeout( function()
{
s = true;
console.log( "Timeout!!!" );
console.log( "s value is " + s );
}, 1000 );
var interval = setInterval(function() {
console.log( "this is while and s is " + s );
i++;
if (s) {
clearInterval(interval);
console.log("i is " + i)
}
}, 100);
});
setTimeout is never called do the the fact that the while never ends and so the even dispatcher is not going to trigger the setTimeout.