是promise.then异步与否?

时间:2016-02-03 17:46:07

标签: javascript infinite-loop es6-promise

以下代码在Firefox和Chrome上挂起,但在Edge上没有:

let sequence = Promise.resolve();
function fire() {
  sequence.then(fire)
};
fire();

我认为它在几个版本之前没有挂在Firefox上,我很困惑。这里的正确行为是什么?

修改:Edge 37.14316现在也挂起了。

3 个答案:

答案 0 :(得分:4)

是的,Promise.then是异步的,但是当您立即解决承诺,然后继续在回调中调用相同的函数时,您将获得无限循环,并且浏览器挂起

简单来说,你正在做

function fire() {
   fire(); // goes on forever
}
fire();

唯一的区别是fire位于已经解决的异步回调中,并立即触发。

如果Edge没有挂起,那只是因为它可以更好地处理递归。

enter image description here

答案 1 :(得分:1)

正确的行为是挂起 1 。你不会得到堆栈溢出,但异步无限递归仍然是无限递归。

1:这是微任务队列中的无限循环。其他承诺工作可能会运行,但没有其他工作。

答案 2 :(得分:1)

它挂起,因为git checkout 0.5.4 链在微任务队列上执行,不像.then在主JavaScript事件队列上执行:

setTimeout

大多数浏览器在当前的run-to-completion的尾部完全清空微任务队列,并且你的代码阻止它永远清空,停止主JavaScript事件队列。

浏览器并非完全挂起,因为用户可以在一段时间后停止此失控脚本。在此期间浏览器的可用性取决于浏览器是否支持多个进程。例如。 Firefox Developer Edition在这方面比Firefox更好,因为dev版本使用多个进程。