function foobar() {
console.log('baz');
setTimeout(() => foobar(), 1000);
}
foobar();
throw new Error('terminate');
我假设foobar
函数将一个在1s之后执行的回调排队,然后退出堆栈,然后main函数抛出错误,并且应该终止。但是,如果它们在浏览器中运行,则不会。
答案 0 :(得分:2)
此示例对此进行了更好的说明:
let attempts = 10;
function foobar() {
if (!attempts--) return; // make it stop!
console.log('baz');
setTimeout(foobar, 1000);
throw new Error('terminate');
}
foobar();
请参见,引发错误会终止当前任务的执行,但不会终止浏览器event loop。事件循环中已经有另一个任务坐在队列中-由setTimeout 排定,然后抛出错误。冲洗并重复。
但是,Node.js领域的情况有所不同:第一个未捕获的异常基本上会停止整个进程的执行。这就是Node的理念-fail early-尽管questioned仍然存在。
仍然,只需进行少量修改,您就会看到类似的图片。只需将以下行添加到脚本中:
process.on('uncaughtException', function (err) {
console.error('CAUGHT', err);
});
...,您会看到非常相似的模式。
答案 1 :(得分:1)
成为JavaScript解释器。
让我们看一下任务列表,JavaScript解释器必须这样做:
[执行主代码]
现在,解释器逐行执行任务。
执行foobar();
的JavaScript解释器将在其任务列表中推送一个新任务,其中包含要执行的setTimeout()
函数。
[执行主要代码(正在进行)] [执行setTimeout函数]
然后,当到达抛出时,它将抛出错误并终止实际的任务执行。
它需要执行下一个任务:
[执行setTimeout函数(正在进行)]
执行setTimeout
函数,它将再次推送一个新任务(与刚刚执行的任务相同)。
一次又一次,一次又一次...
function foobar() {
console.log('baz');
setTimeout(() => foobar(), 1000);
}
foobar();
throw new Error('terminate');