为什么长时间不运行JavaScript承诺块?

问题描述

如果一个promise创建了一个新的微任务回调,并且在处理下一个宏任务之前已解决了所有微任务,为什么不保证promise会阻塞事件循环?

这里是一个答案,解释了诺言就像事件通知系统一样,显然这是正确的,因为诺言不会阻塞,这就是重点:

Do Javascript promises block the stack

但是要清楚一点,如果将回调添加到微队列中,并且必须清空该队列以继续执行下一个宏任务,为什么它不阻塞?

解决方法

它确实会阻止,例如您可能会在微任务检查点被阻止。

const block_loop = () => Promise.resolve().then( block_loop );

document.getElementById('btn').onclick = evt => {
  if( confirm("this will block this page") ) {
    block_loop();
  }
};
<button id="btn">block the event loop</button>
This frame will get blocked.

此示例不会阻塞任务的来源,但是由于从微任务端点排队的微任务将排队在要清空的同一微任务队列中,因此实际上您将陷入无尽的循环,并且事件循环将无法处理任何将来的任务。

微任务也是任务,它们的处理本身也会像其他任何任务一样阻塞事件循环:

const block_loop = () => {
  const start = performance.now();
  while( performance.now() - start < 10000 ) {
    
  }
};
document.getElementById('btn').onclick = evt => {
  if( confirm("this will block this page for 10s") ) {
    Promise.resolve().then( block_loop );
  }
};
<button id="btn">block the event loop</button>
This frame will get blocked.

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...