在setInterval内部睡眠而不冻结浏览器

时间:2016-07-15 15:23:36

标签: javascript setinterval sleep

我有一个名为" 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上也很常见,因为它们通常一次只做一件事。一个JS模拟器,其目的是尽可能准确地复制Arduino语法,当然需要一个同步延迟函数。

1 个答案:

答案 0 :(得分:-2)

修改: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>

正如您在控制台中看到的那样,它会一次又一次地打印“一些代码”和“更多代码”,其间的同步延迟为1000毫秒。即使我们这样做,UI也不会冻结,文本动画也能顺利运行。