admin管理员组文章数量:1323524
Javascript's setInterval() seems to pay no attention to whether or not the code it calls throws exceptions. For instance, this will not terminate the program but call the function over and over again:
setInterval(function() { throw "error" }, 1000);
What is the reason for this behaviour? Is it documented anywhere?
Javascript's setInterval() seems to pay no attention to whether or not the code it calls throws exceptions. For instance, this will not terminate the program but call the function over and over again:
setInterval(function() { throw "error" }, 1000);
What is the reason for this behaviour? Is it documented anywhere?
Share Improve this question asked Aug 6, 2014 at 23:02 Eugene YarmashEugene Yarmash 150k44 gold badges343 silver badges388 bronze badges 18- "will not terminate the program" --- how do you see that? As the whole browser tab crash? – zerkms Commented Aug 6, 2014 at 23:03
- What could possibly handle the exception sanely? – Ignacio Vazquez-Abrams Commented Aug 6, 2014 at 23:07
- Async callbacks and try...catch don't mix. – elclanrs Commented Aug 6, 2014 at 23:07
-
1
@Vivin Paliath:
setInterval
callback does terminate. – zerkms Commented Aug 6, 2014 at 23:13 -
1
@Vivin Paliath: well, a particular callback execution does terminate. Not sure why the whole iterative process should.
setInterval
just schedules a function invocation. – zerkms Commented Aug 6, 2014 at 23:16
3 Answers
Reset to default 6The MDN docs for throw
say, for a thrown object:
If no catch block exists among caller functions, the program will terminate.
This isn't strictly accurate. ECMAScript spec section 10.4
A thrown exception may also exit one or more execution contexts.
This is more accurate.
What is an execution context? Well, there's one for your original program. When you make a function call, a nested context is created while that function is running. A call to eval
will make one. 10.4 covers this.
In general, when an exception is thrown, it will pass up through all of the nested execution contexts until it is caught, or it reaches the outer execution context. If it is not caught within an execution context, that context will be terminated. Thus, if your original program is the outermost execution context, it will terminate on an uncaught exception?
When your handler function is called, due to your setTimeout
interval expiring, it is the outermost execution context. Thus, the uncaught exception terminates it, but it is not nested within your original program. So nothing else gets terminated.
The thread that's handling the timer expires is part of the JS engine, so you're not going to terminate that either. Thus, once per interval, a new execution context is created when your handler function is called and so it repeats.
If you don't want the function to be called over and over again, catch the exception and clear the timer. This example counts down from five, printing to the console, and throws an exception when the value is less than zero:
var counter = 5;
var timer;
var decrement = function() {
try {
if ( counter < 0 ) {
clearInterval(timer);
throw new Error("Invalid count");
}
console.log(counter);
counter -= 1;
}
catch ( error ) {
console.error(error);
}
}
timer = setInterval(decrement, 1000);
It is up to you to decide if the function should or should not be called again. An exception stops execution of the function but there is no "program" to terminate. The web browser is the "program". If it runs a function that throws an exception, it still continues to service other events. That is the expected behavior.
Why doesn't it cancel the timer on an exception? You may want that when trying to load a resource that may fail and clear the timer on success.
When you call setInterval
, the runtime doesn't know if the callback will throw.
var shouldThrow = false;
setInterval(function () {
if (shouldThrow) throw 'error';
console.log('program has not stopped');
}, 5000);
// nothing is wrong at this point.
// thus, the program continues
shouldThrow = confirm('Throw error?');
You'll find that if the callback throws, it does terminate "the program," that being the callback itself. In this example, if you click the OK button, the callback will not proceed to the console.log
call. It does continue to call the callback repeatedly though. If you later change shouldThrow
again, you'll see more messages in the console.
本文标签: javascriptWhy does setInterval() ignore errorsStack Overflow
版权声明:本文标题:javascript - Why does setInterval() ignore errors? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742130630a2422141.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论