以下代码在Firefox和Chrome上挂起,但在Edge上没有:
let sequence = Promise.resolve();
function fire() {
sequence.then(fire)
};
fire();
我认为它在几个版本之前没有挂在Firefox上,我很困惑。这里的正确行为是什么?
修改:Edge 37.14316现在也挂起了。
答案 0 :(得分:4)
是的,Promise.then
是异步的,但是当您立即解决承诺,然后继续在回调中调用相同的函数时,您将获得无限循环,并且浏览器挂起
简单来说,你正在做
function fire() {
fire(); // goes on forever
}
fire();
唯一的区别是fire
位于已经解决的异步回调中,并立即触发。
如果Edge没有挂起,那只是因为它可以更好地处理递归。
答案 1 :(得分:1)
正确的行为是挂起 1 。你不会得到堆栈溢出,但异步无限递归仍然是无限递归。
1:这是微任务队列中的无限循环。其他承诺工作可能会运行,但没有其他工作。
答案 2 :(得分:1)
它挂起,因为git checkout 0.5.4
链在微任务队列上执行,不像.then
在主JavaScript事件队列上执行:
setTimeout
大多数浏览器在当前的run-to-completion的尾部完全清空微任务队列,并且你的代码阻止它永远清空,停止主JavaScript事件队列。
浏览器并非完全挂起,因为用户可以在一段时间后停止此失控脚本。在此期间浏览器的可用性取决于浏览器是否支持多个进程。例如。 Firefox Developer Edition在这方面比Firefox更好,因为dev版本使用多个进程。