有没有更快的替代方案window.requestAnimationFrame()
对于不阻塞 I/O 的无限循环?
我在循环中所做的事情与动画无关,所以我不在乎下一帧何时准备好,并且我已经读过window.requestAnimationFrame()
受到监视器刷新率的限制,或者至少等待直到可以绘制帧。
我也尝试过以下方法:
function myLoop() {
// stuff in loop
setTimeout(myLoop, 4);
}
(4是因为这是最小间隔setTimeout
较小的值仍默认为 4。)但是,我需要比这更好的分辨率。
还有比这更好的性能吗?
我基本上需要一个非阻塞版本while(true)
.
有两件事会比这更快地运行setTimeout
:
因此,这些可能是您工具带上的工具,将其中一个或两个与setTimeout
达到你想要的平衡。
Details:
您可能知道,给定的 JavaScript 线程在任务队列的基础上运行(规范将其称为作业队列);您可能知道,浏览器中有一个主要的默认 UI 线程,而 NodeJS 运行单个线程。
但实际上,现代实现中至少有两个任务队列:我们都想到的主要一个(其中setTimeout
和事件处理程序放置其任务),以及在处理主任务(或“宏任务”)期间放置某些异步操作的“微任务”队列。一旦宏任务完成,这些微任务就会被处理,before主队列中的下一个宏任务 - 即使下一个宏任务在微任务之前排队。
nextTick
回调和承诺结算通知都是微任务。因此,调度要么调度异步回调,但该回调将在下一个主要任务之前发生。
我们可以在浏览器中看到setInterval
和一个承诺解析链:
let counter = 0;
// setInterval schedules macrotasks
let timer = setInterval(() => {
$("#ticker").text(++counter);
}, 100);
// Interrupt it
$("#hog").on("click", function() {
let x = 300000;
// Queue a single microtask at the start
Promise.resolve().then(() => console.log(Date.now(), "Begin"));
// `next` schedules a 300k microtasks (promise settlement
// notifications), which jump ahead of the next task in the main
// task queue; then we add one at the end to say we're done
next().then(() => console.log(Date.now(), "End"));
function next() {
if (--x > 0) {
if (x === 150000) {
// In the middle; queue one in the middle
Promise.resolve().then(function() {
console.log(Date.now(), "Middle");
});
}
return Promise.resolve().then(next);
} else {
return 0;
}
}
});
$("#stop").on("click", function() {
clearInterval(timer);
});
<div id="ticker"> </div>
<div><input id="stop" type="button" value="Stop"></div>
<div><input id="hog" type="button" value="Hog"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
当您运行该程序并单击Hog按钮,注意计数器显示如何冻结,然后又继续显示。这是因为提前安排了 300,000 个微任务。另请注意我们编写的三个日志消息上的时间戳(它们不会出现在代码片段控制台中,直到宏任务显示它们,但时间戳向我们显示它们的记录时间)。
所以基本上,您可以安排一堆微任务,并定期让这些微任务运行完并运行下一个宏任务。
Note: 我用过setInterval
对于代码片段中的浏览器示例,但是setInterval
,具体来说,对于使用 NodeJS 的类似实验来说可能不是一个好的选择,因为 NodeJS 的setInterval
与浏览器中的有点不同,并且具有一些令人惊讶的计时特征。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)