setInterval 的持续时间
Duration of setInterval
我创建了一个简单的函数,它在 3 秒内将值从 0 计数到某个值。
这里是 fiddle - https://jsfiddle.net/ar6akv5z/ 和片段:
var number = document.querySelector('.number');
var button = document.querySelector('button');
button.addEventListener('click', function() {
counting(number, 2500);
})
function counting(elem, value) {
var count = 0;
var timerId = setInterval(function() {
if (++count == value) clearInterval(timerId);
elem.innerHTML = count;
}, 3000/value);
}
<span class="number">0</span>
<button>Go</button>
但是函数的持续时间超过了3秒。
你能解释一下为什么会这样或者告诉我我的错误吗?
谢谢,对不起我的英语
计时器的最小间隔受制于 an algorithm 指定的是 HTML5 规范(最初它在现已失效的计时器规范中),以防止计时器触发得太快。当定时器调度定时器时(本质上就是setInterval
所做的),一旦嵌套达到五层,如果请求的定时器间隔<4ms,则设置为4ms:
- If nesting level is greater than 5, and timeout is less than 4, then increase timeout to 4.
由于您告诉它在每次计时器触发时加 1,而且它很快开始每 4 毫秒触发一次(最多),因此需要 4 * 2500 = 10000 毫秒(10 秒)才能完成。
您可以在下面更新的代码段中看到这个平均延迟,它用回调之间的平均时间替换了计数器:
if (!Date.now) {
Date.now = function() {
return +new Date();
};
}
var number = document.querySelector('.number');
var button = document.querySelector('button');
var sum = 0;
var last = null;
button.addEventListener('click', function() {
counting(number, 2500);
})
function counting(elem, value) {
var count = 0;
last = Date.now();
var timerId = setInterval(function() {
var now = Date.now();
sum += now - last;
last = now;
if (++count == value) clearInterval(timerId);
elem.innerHTML = sum / count;
}, 3000/value);
}
<span class="number">0</span>
<button>Go</button>
setTimeout
和 setInterval
规定了最短延迟。来自 MDN
Reasons for delays longer than specified
Nested timeouts forced to >=4ms
Historically browsers implement setTimeout() "clamping": successive setTimeout() calls with delay smaller than the "minimum delay" limit are forced to use at least the minimum delay. The minimum delay, DOM_MIN_TIMEOUT_VALUE, is 4 ms (stored in a preference in Firefox: dom.min_timeout_value), with a DOM_CLAMP_TIMEOUT_NESTING_LEVEL of 5.
In fact, 4 ms is specified by the HTML5 spec and is consistent across browsers released in 2010 and onward. Prior to (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), the minimum timeout value for nested timeouts was 10 ms.
因此,即使您指定 3000/2500 = 1.2
作为间隔时间,它的作用就好像您使用 4
作为间隔时间一样。
我创建了一个简单的函数,它在 3 秒内将值从 0 计数到某个值。
这里是 fiddle - https://jsfiddle.net/ar6akv5z/ 和片段:
var number = document.querySelector('.number');
var button = document.querySelector('button');
button.addEventListener('click', function() {
counting(number, 2500);
})
function counting(elem, value) {
var count = 0;
var timerId = setInterval(function() {
if (++count == value) clearInterval(timerId);
elem.innerHTML = count;
}, 3000/value);
}
<span class="number">0</span>
<button>Go</button>
但是函数的持续时间超过了3秒。 你能解释一下为什么会这样或者告诉我我的错误吗?
谢谢,对不起我的英语
计时器的最小间隔受制于 an algorithm 指定的是 HTML5 规范(最初它在现已失效的计时器规范中),以防止计时器触发得太快。当定时器调度定时器时(本质上就是setInterval
所做的),一旦嵌套达到五层,如果请求的定时器间隔<4ms,则设置为4ms:
- If nesting level is greater than 5, and timeout is less than 4, then increase timeout to 4.
由于您告诉它在每次计时器触发时加 1,而且它很快开始每 4 毫秒触发一次(最多),因此需要 4 * 2500 = 10000 毫秒(10 秒)才能完成。
您可以在下面更新的代码段中看到这个平均延迟,它用回调之间的平均时间替换了计数器:
if (!Date.now) {
Date.now = function() {
return +new Date();
};
}
var number = document.querySelector('.number');
var button = document.querySelector('button');
var sum = 0;
var last = null;
button.addEventListener('click', function() {
counting(number, 2500);
})
function counting(elem, value) {
var count = 0;
last = Date.now();
var timerId = setInterval(function() {
var now = Date.now();
sum += now - last;
last = now;
if (++count == value) clearInterval(timerId);
elem.innerHTML = sum / count;
}, 3000/value);
}
<span class="number">0</span>
<button>Go</button>
setTimeout
和 setInterval
规定了最短延迟。来自 MDN
Reasons for delays longer than specified
Nested timeouts forced to >=4ms
Historically browsers implement setTimeout() "clamping": successive setTimeout() calls with delay smaller than the "minimum delay" limit are forced to use at least the minimum delay. The minimum delay, DOM_MIN_TIMEOUT_VALUE, is 4 ms (stored in a preference in Firefox: dom.min_timeout_value), with a DOM_CLAMP_TIMEOUT_NESTING_LEVEL of 5.
In fact, 4 ms is specified by the HTML5 spec and is consistent across browsers released in 2010 and onward. Prior to (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), the minimum timeout value for nested timeouts was 10 ms.
因此,即使您指定 3000/2500 = 1.2
作为间隔时间,它的作用就好像您使用 4
作为间隔时间一样。