javascript - 事件循环和同步阻塞
问题描述
我正在浏览“不耐烦的程序员的 JS”,我遇到了以下代码。
我试图了解同步性质以及为什么Blocking...
要在sleep(5000)
.
我相信代码的目的是在Blocking...
发生阻塞时出现在屏幕上,但当我在 JSFiddle 中输入它时,这并不是实际响应
document.getElementById('block')
.addEventListener('click', doBlock);
function doBlock(event) {
setStatus('Blocking...');
sleep(5000);
setStatus('Done');
}
function sleep(milliseconds) {
const start = Date.now();
while ((Date.now() - start) < milliseconds);
}
function setStatus(status) {
document.getElementById('statusMessage')
.textContent = status;
}
<a id="block" href="#">Block</a>
<div id="statusMessage"></div>
<button>Click me!</button>
解决方案
我可以与以下稍微修改的HTML/JS 代码分享我的发现吗?
- Chromium 版本 73.0.3683.75(openSUSE Build)(64 位)按预期工作。
- Firefox Developer Edition 67b6(64 位)偶尔会按预期工作。
- Firefox Stable Quantum 60.6.1 ESR(64 位)仍然无法按预期工作。
但是,如果您移动到const delayBlocking = 50
毫秒延迟,它还会在 Firefox Stable Quantum 60.6.1 ESR 浏览器上显示“Blocking...”。
我的解释是(根据 Mark 在评论中所说的)必须给浏览器时间来更新 DOM。浏览器必须能够呈现至少一帧,显示在进入阻塞状态之前呈现的“阻塞...”状态消息(此处为 5 秒)。这可以通过适当调整的 setTimeout 来完成,如下所示。——问候,M。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Document</title>
</head>
<body>
<a id="block" href="#">Block</a>
<div id="statusMessage"></div>
<button>Click me!</button>
<script>
document.getElementById('block')
.addEventListener('click', doBlock);
function doBlock(event) {
setStatus('Blocking...');
// Introducing some ...
const delayBlocking = 0;
setTimeout(function() {
sleep(5000);
setStatus('Done');
}, delayBlocking);
}
function sleep(milliseconds) {
const start = Date.now();
while ((Date.now() - start) < milliseconds);
}
function setStatus(status) {
document.getElementById('statusMessage')
.textContent = status;
}
</script>
</body>
</html>
推荐阅读
- zend-framework - 如何从另一个模块提供服务?
- c# - 如何将信息从视图传递到控制器作为参数
- angular - 如何将 ngFor 用于集合中的数组
- python - 设置 Python KafkaProducer sasl 机制属性
- r - R中lm()回归的summary()中的“剩余标准误差”是什么意思?
- android - 我可以在特定时间暂时停止通过我的应用打开其他应用吗?
- asp.net - 将旧的 VB.NET 项目从 VS2013 迁移到 VS2017
- android-studio - Android Studio 损坏的 .studio 而不是 classes 显示难以理解的部分 – xml
- jekyll - Jekyll 忽略第二个配置文件
- ios - Xcode 11 beta 5 - 不支持的 Xcode 错误