在不冻结浏览器的情况下在 setInterval 中休眠

Sleep inside of setInterval without freezing the browser

我有一个名为 "loop" 的函数,该函数正在使用 setInterval() 重复调用。在该函数内部,我需要另一个必须称为 "delay()" 的函数(它必须是确切的语法)。

所以我得到了这个:

function loop() {
    console.log("some code")
    delay(100)
    console.log("some more code")
    delay(100)
}



if (typeof loop != "undefined")
    window.loopInterval = setInterval(loop, 1)

function delay(millis) {
    var now = Date.now();
    while(Date.now() < now + millis){} 
}

这工作得很好,但它会冻结浏览器,使其无法正确呈现某些更改。
现在有什么方法可以更改延迟函数,以便它只是暂时暂停 setInterval?

正如我所说,循环和延迟函数的语法必须保持不变。是的,我有充分的理由。

对于所有不相信我的人,我确实有一个很好的理由,在这里:https://github.com/T-vK/LedStripSimulator
为 Arduinos 编写的代码几乎总是使用 loop() 函数,而 delay() 在 Arduinos 上也是很常见的事情,因为他们通常一次只做一件事。而一个以尽可能准确地复制Arduino语法为目的的JS模拟器当然需要同步延迟功能。

编辑:Here is a complete project I've been working on that easily demonstrates that it works.

我想通了......我只需要 运行 我的代码在一个单独的线程中。在那个线程中我可以睡一整天并且 DOM 渲染不会受到影响。

(浏览器必须支持网络工作者)

//Code that runs in a separate thread:
var blob = new Blob([`
    function loop() {
        console.log("some code");
        delay(1000);
        console.log("some more code");
        delay(1000);
    }
    function delay(millis) {
        var now = Date.now();
        while(Date.now() < now + millis){} ;
    }
    if (typeof loop != "undefined")
        setInterval(loop, 1);
`], { type: "text/javascript" });

var worker = new Worker(window.URL.createObjectURL(blob));

//Code that runs in the UI thread:
var text = 'This text will be added to this div letter by letter without any freezing from the delay() function.';
var currentLetter = 0;
var maxLetter = text.length-1;
var div = document.getElementById('lagFree');

setInterval(function() {
    div.innerHTML = div.innerHTML + text[currentLetter];
    if (currentLetter >= maxLetter) {
        div.innerHTML = '';
        currentLetter = 0;
    } else
        currentLetter++;
},10);
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
</head>
<body>
  <div id="lagFree"></div>
</body>
</html>

正如您在控制台中看到的那样,它一次又一次地打印 "some code" 和 "some more code",中间有 1000 毫秒的同步延迟。即使我们这样做了,UI 也不会冻结并且文本动画 运行 很流畅。