【发布时间】:2019-11-18 03:14:42
【问题描述】:
我不明白为什么调用recSetTimeOut() 不会导致堆栈溢出错误,而recPromise() 会。
const recSetTimeOut = () => {
console.log('in recSetTimeOut');
setTimeout(recSetTimeOut, 0)
};
recSetTimeOut();
const recPromise = () => {
console.log('in recPromise');
Promise.resolve().then(recPromise);
}
recPromise();
为什么会这样?它们有什么区别?
你能解释一下幕后的过程吗?
编辑更多信息
在Node.js v12.1.0 和Chrome DevTools 上运行这个sn-ps:
const recSetTimeOut = () => { setTimeout(recSetTimeOut, 0); }
recSetTimeOut();
结果Node:没有错误。
结果Chrome:没有错误。
const recPromise = () => { Promise.resolve().then(recPromise); }
recPromise();
结果Node:
致命错误:无效的表大小分配失败 - JavaScript 堆内存不足
结果Chrome:浏览器崩溃。
【问题讨论】:
-
赞成使堆栈溢出成为动词。
-
无递归。 “递归”
recSetTimeout调用实际上是预定的,并且不是当前函数堆栈的一部分。每次回调,栈都是干净的,只有调度器在栈顶。 -
@Amy,Promise 也不是,对吧? Promise 总是异步的?
-
您可以通过发出异常并检查堆栈跟踪来验证这一点。
-
如前所述,我认为这在任何时候都不会产生堆栈溢出。事情变慢了,但那是因为你不断地运行代码,调度程序、GC 等需要跟上。如果您看到 actual 堆栈溢出消息,请记住将其添加到您的问题中。如果不是:最好提及您所看到的,而不是提及堆栈溢出。
标签: javascript