我想知道javascript中setTimeout方法的准确性。它是否具有任何超过阈值的阈值,它将完全推迟这么多毫秒,或者它是否完全执行指定的功能而不管毫秒值。
答案 0 :(得分:8)
JavaScript没有setTimeout
方法。浏览器和运行JavaScript的其他一些环境。
HTML5规范为§6.4- Timers中的浏览器setTimeout
及其堂兄弟(通常称为“计时器”)制定了规则。
一般情况下,计时器会合理地 ,只要其回调需要运行的线程不忙于执行其他操作。但这是一个很大的附带条件。如果线程忙,则无法运行回调并且将在作业队列中等待,直到线程到达它,因此您无法确定它是否会在预期时触发,特别是如果您正在使用默认线程JavaScript在浏览器中运行,用于处理UI。它不会运行之前的, 1 ,但它可能会比您预期的更晚运行。
浏览器还会更改计时器在运行窗口时以各种方式运行的方式(例如,它是非活动选项卡)。
这是一个片段,用于衡量您的浏览器在主UI线程上的效果:
var results = [];
var disp = {
min: document.getElementById("min").firstChild,
max: document.getElementById("max").firstChild,
avg: document.getElementById("avg").firstChild,
count: document.getElementById("count").firstChild
};
var now = (function() {
if (typeof performance !== "undefined" && performance.now) {
return function() {
return performance.now();
};
}
return function() {
return Date.now();
};
})();
function test() {
var delay = Math.floor(Math.random() * 50) + 10;
var start = now();
setTimeout(function() {
var elapsed = now() - start;
var result = {
delay: delay,
elapsed: elapsed,
diff: elapsed - delay
};
logResult(result);
results.push(result);
if (results.length <= 500) {
test();
}
}, delay)
}
function log(msg, atTop) {
var p = document.createElement('p');
p.innerHTML = msg;
if (atTop) {
p.style.borderBottom = "1px solid black";
document.body.insertBefore(p, document.body.firstChild);
} else {
document.body.appendChild(p);
}
}
function logResult(r) {
log("expected " + r.delay + ", got " + r.elapsed + ", diff: " + r.diff);
summary();
}
function summary() {
var sum = 0,
min = Infinity,
max = -Infinity;
results.forEach(function(r) {
var d = r.diff;
sum += d;
min = Math.min(min, d);
max = Math.max(max, d);
});
disp.min.nodeValue = min.toFixed(4);
disp.max.nodeValue = max.toFixed(4);
disp.avg.nodeValue = (sum / results.length).toFixed(4);
disp.count.nodeValue = results.length;
}
setTimeout(test, 500);
.summary {
border-bottom: 1px solid #ddd;
padding-bottom: 4px;
}
<div class="summary">
Variance in milliseconds:
<br>
Min: <span id="min">-</span> |
Max: <span id="max">-</span> |
Avg: <span id="avg">-</span> |
Count: <span id="count">-</span>
</div>
1 “...它将无法运行之前的 ...” - 显然(来自上面的代码段)在Firefox上可以提前几分之一毫秒。我把它归结为计时器在整整几毫秒内工作的事实。显然如果你在12:30:04.0415(在12:30:04和41ms后半毫秒)安排一个计时器20ms,它将在12:30:04.061(12:30:04再加上61ms)开始计时比等到12:30:04.0615(12:30:04再加上61.5ms)。例如,显然它需要12:30:04.0415,忽略得到12:30:04.041的小数毫秒,加上20到12:30:04.061,然后在它之后尽快开火。
答案 1 :(得分:1)
您应该假设任何超时功能将等待“至少”指定的时间段。但它可能会更长。 “多长时间”是不可预测的。
答案 2 :(得分:1)
取决于实施和环境。
有许多因素,例如浏览器端,非活动标签和用户设置,服务器端和操作系统交互。