javascript - 为什么不长时间运行 javascript 承诺阻止?
问题描述
如果一个 Promise 创建了一个新的微任务回调,并且所有微任务在处理下一个宏任务之前都已解决,那么为什么 Promise 不阻塞事件循环?
这是解释承诺就像一个事件通知系统的答案,显然这是真的,因为承诺不会阻塞,这就是重点:
但是要明确一点,如果将回调添加到微队列中,并且必须清空该队列才能继续执行下一个宏任务,为什么它不阻塞?
解决方案
它确实会阻塞,例如,您可能会在微任务检查点中被阻塞。
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.
推荐阅读
- php - 调用未定义函数 mysqli_connect()
- r - 如何使用正则表达式匹配 R 中使用 gsub 的第三个正斜杠?
- python - 字符串文字中的正斜杠行为异常
- javascript - 套接字 io 中的回调未按预期工作
- c# - cancelTOken 和同步 sql 调用的计时问题
- api - 从代码调用时,获取 Swagger API 响应错误 StatusCode 404
- c - 在 ARM Cortex-M 系列上确定函数的返回地址
- java - 我在 WebSphere 应用程序服务器上初始化 SparkContext 时遇到 SparkContext 错误
- machine-learning - 如何为我的机器学习问题建模?
- sql - SQL - 在没有游标或 sp_foreach 的情况下删除实例上所有数据库上的用户