首页 > 解决方案 > 为什么不长时间运行 javascript 承诺阻止?

问题描述

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

这是解释承诺就像一个事件通知系统的答案,显然这是真的,因为承诺不会阻塞,这就是重点:

Javascript Promise 会阻塞堆栈吗

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

标签: javascriptevent-loop

解决方案


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

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.


推荐阅读