我有一个名为" 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语法,当然需要一个同步延迟函数。
答案 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也不会冻结,文本动画也能顺利运行。