This question already has answers here:
How does setTimeout prevent potential stackoverflow
(2 answers)
Why the function called by setTimeout has no callstack limit?
(2 answers)
Closed 5 years ago.
By using javascript recursive setTimeout function, is it risky to get the stackoverflow?
By trying this example you can see in browser console that the stack grows. Why is it so?
var iteration = 0;
function bar() {
iteration++;
console.log("iteration: " + iteration);
console.trace();
if(iteration < 5){
setTimeout(bar, 5000);
}
}
bar();
By using javascript recursive setTimeout function, is it risky to get the stackoverflow?
No. setTimeout registers a handler that will get called by the browser when the timer triggers. By the time that happens, the stack has unwound (if it hadn't, the task that scheduled the timeout wouldn't have ended, and the browser's UI would be locked up waiting for it to end).
By trying this example you can see in browser console that the stack grows.
No, the stack unwinds before the handler is next called. If you're referring to the async "stack" entries that Chrome's devtools show you, those aren't the real stack, and they're a devtools artifact. (Start your timer, watch for two ticks so you see the "async" entry on the second one, then close your console, wait two more ticks, and reopen it; notice that there aren't any "async" entries — at all, not even the one you saw it log before closing the console!)
Related
This question already has answers here:
How does setTimeout prevent potential stackoverflow
(2 answers)
Why the function called by setTimeout has no callstack limit?
(2 answers)
Closed 5 years ago.
By using javascript recursive setTimeout function, is it risky to get the stackoverflow?
By trying this example you can see in browser console that the stack grows. Why is it so?
var iteration = 0;
function bar() {
iteration++;
console.log("iteration: " + iteration);
console.trace();
if(iteration < 5){
setTimeout(bar, 5000);
}
}
bar();
By using javascript recursive setTimeout function, is it risky to get the stackoverflow?
No. setTimeout registers a handler that will get called by the browser when the timer triggers. By the time that happens, the stack has unwound (if it hadn't, the task that scheduled the timeout wouldn't have ended, and the browser's UI would be locked up waiting for it to end).
By trying this example you can see in browser console that the stack grows.
No, the stack unwinds before the handler is next called. If you're referring to the async "stack" entries that Chrome's devtools show you, those aren't the real stack, and they're a devtools artifact. (Start your timer, watch for two ticks so you see the "async" entry on the second one, then close your console, wait two more ticks, and reopen it; notice that there aren't any "async" entries — at all, not even the one you saw it log before closing the console!)
This question already has answers here:
Callback of an asynchronous function is never called
(1 answer)
setTimeout not working inside infinite loop
(5 answers)
Closed 5 years ago.
Can't explain nodejs behavior. I have code:
while (true) {
setTimeout(() => console.log(1), 0)
}
And this script just hanging...
How come? I've been thinking setTimeout is non-blocking and asynchronous, and nodejs use timers event loop phase for scheduling setTimeout callbacks... but it seems like event loop blocked...
Your while loop is infinite. It will just keep setting timeouts and never exiting the loop. Since JavaScript is single-threaded, the code for the timeouts won't run until the current code is finished, and since the while loop never finishes, the timeouts don't run.
If you want to spam the console with the number 1 using timeouts, which it looks like you are trying to do, you would have to set the next timeout in the current timeout's callback:
function timeoutFunc() {
console.log(1);
setTimeout(timeoutFunc, 0);
}
timeoutFunc();
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.
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.
This question already has answers here:
What is the JavaScript version of sleep()?
(91 answers)
Closed 3 years ago.
Is there a JavaScript function that simulates the operation of the sleep function in PHP — a function that pauses code execution for x milliseconds, and then resumes where it left off?
I found some things here on Stack Overflow, but nothing useful.
You need to re-factor the code into pieces. This doesn't stop execution, it just puts a delay in between the parts.
function partA() {
...
window.setTimeout(partB,1000);
}
function partB() {
...
}
You can't (and shouldn't) block processing with a sleep function. However, you can use setTimeout to kick off a function after a delay:
setTimeout(function(){alert("hi")}, 1000);
Depending on your needs, setInterval might be useful, too.
setTimeout() function it's use to delay a process in JavaScript.
w3schools has an easy tutorial about this function.