【发布时间】:2016-12-03 22:17:42
【问题描述】:
我必须使用至少 2 个 setTimeouts 和 1 个 setInterval。这对正在使用的浏览器或 javascript 引擎有任何依赖吗?
【问题讨论】:
标签: javascript settimeout
我必须使用至少 2 个 setTimeouts 和 1 个 setInterval。这对正在使用的浏览器或 javascript 引擎有任何依赖吗?
【问题讨论】:
标签: javascript settimeout
tl;dr:在创建 10 万个计时器之前,不要担心计时器的成本。
我刚刚通过创建这个测试文件对计时器性能进行了快速测试(一遍又一遍地创建 100K 计时器):
<script>
var n = 0; // Counter used to verify all timers fire
function makeTimers() {
var start = Date.now();
for (var i = 0; i < 100000; i++, n++) {
setTimeout(hello, 5000);
}
console.log('Timers made in', Date.now() - start, 'msecs');
}
function hello() {
if (--n == 0) {
console.log('All timers fired');
makeTimers(); // Do it again!
}
}
setTimeout(makeTimers, 10000); // Wait a bit before starting test
</script>
我在大约 2014 年左右的 Macbook Pro 上的 Google Chrome (v54) 中打开了这个文件,然后转到开发人员工具中的时间轴选项卡,并在加载页面时记录内存配置文件,并运行了 3-4 个测试周期。
观察
计时器创建循环需要 200 毫秒。页面堆大小从 3.5MB 预测试开始,然后稳定在 3.9MB。
结论
每个计时器需要约 0.002 毫秒来设置,并向 JS 堆添加大约 35 个字节。
【讨论】:
在一个页面上,您可以根据需要同时运行多个 setTimeouts/setInterval,但是为了单独控制每个,您需要将它们分配给一个变量。
var interval_1 = setInterval("callFunc1();",2000);
var interval_2 = setInterval("callFunc2();",1000);
clearInterval(interval_1);
上面的代码同样适用于 setTimeout,只是替换了措辞。
正如 Kevin 所说,JavaScript 确实是单线程的,所以虽然您可以同时运行多个计时器,但在任何时候只有一个计时器可以触发 - 即,如果您有一个触发“暂停”执行的函数,例如带有一个警告框,那么我相信必须在另一个可以触发之前“恢复”该 JS。
下面再举一个例子。虽然标记无效,但它显示了超时的工作原理。
<html>
<body>
<script type="text/javascript">
function addThing(){
var newEle = document.createElement("div");
newEle.innerHTML = "Timer1 Tick";
document.body.appendChild(newEle);
}
var t1= setInterval("addThing();",1000);
var t2 = setInterval("alert('moo');",2000);
</script>
</body>
</html>
【讨论】:
您可以根据需要使用任意数量。请记住,JavaScript 是单线程的,因此它们都不能并行执行。
【讨论】:
var interval_1 = setInterval("callFunc1();",2000); 调用 eval() 这是邪恶的,所以很糟糕。
改用这个var interval_1 = setInterval(callFunc1,2000);
对于这个问题,你可以使用尽可能多的,但如果两个动作之间的间隔相同,你最好这样做
var interval = setInterval(function() {
// function1
fct1();
// function2
fct2();
},2000);
【讨论】:
eval 既不邪恶也不邪恶。将字符串传递给setTimeout 进行评估而不是回调is。
eval 可能会无缘无故地让您的代码变慢且可读性降低。大多数(全部?)时间,如果您想使用 eval ,这是因为你还没有充分理解你想要做什么和/或 JavaScript。”所以eval is 是邪恶的(这并不意味着没用,它真的很想使用它,但除非你真的必须这样做,否则你不应该使用它)和eval 的这个用例 不好,因为它可以很容易地在没有 eval 的情况下重写。