简体   繁体   English

Promise.then是否异步?

[英]Is promise.then asynchronous or not?

The following code hangs on Firefox and Chrome but not on Edge: 以下代码挂在Firefox和Chrome上,但不挂在Edge上:

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

I think it didn't hang on Firefox a few versions ago, I'm confused. 我觉得它在Firefox的几个版本上没有挂起,我很困惑。 What is the correct behavior here? 这里正确的行为是什么?

Edit: Edge 37.14316 now hangs too. 编辑:边缘37.14316现在也挂起。

Yes, Promise.then is async, but when you resolve the promise right away, and then keep calling the same function inside the callback, you get an infinite loop, and the browser hangs 是的, Promise.then是异步的,但是当您立即解决promise,然后继续在回调中调用相同的函数时,您将陷入无限循环,浏览器将挂起

In simpler terms, you're doing 简单来说,您正在做

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

The only difference is fire is in an asynchronous callback that is already resolved, and fires right away. 唯一的区别是, fire是在已解决的异步回调中,并立即触发。

If Edge doesn't hang, it's just because it can handle the recursion better. 如果Edge没有挂起,那仅仅是因为它可以更好地处理递归。

在此处输入图片说明

The correct behaviour is to hang 1 . 正确的行为是挂1 You won't get a stack overflow, but asynchronous infinite recursion is still infinite recursion. 您不会出现堆栈溢出,但是异步无限递归仍然是无限递归。

1: It's an endless loop in the microtask queue. 1:这是微任务队列中的一个无限循环。 Other promise jobs might get to run, but not much else. 其他promise作业可能可以运行,但除此之外没有太多。

It hangs because .then chains execute on the microtask queue, unlike eg setTimeout which executes on the main JavaScript event queue: 它挂起,因为.then链执行的microtask队列,不像如setTimeout ,其执行主JavaScript事件队列:

let sequence = Promise.resolve();
function fire() {
  setTimeout(fire); // doesn't hang
};
fire();

Most browsers empty the microtask queue completely at the tail of the current run-to-completion, and your code prevents it from ever emptying, stalling the main JavaScript event queue. 大多数浏览器会在当前运行结束时完全清空微任务队列,并且您的代码会阻止它永远清空,从而使主JavaScript事件队列停滞不前。

The browser isn't totally hung, since users can stop this out-of-control script after a while. 浏览器并未完全挂起,因为用户可以在一段时间后停止此失控脚本。 How usable the browser feels during this period depends on whether the browser supports multiple processes or not. 浏览器在此期间的感觉取决于浏览器是否支持多个进程。 Eg Firefox Developer Edition fares better than Firefox here, since dev edition uses multiple processes. 例如,Firefox开发人员版比Firefox更好,因为开发版使用多个进程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM