让我先说明我完全清楚JS中的计时器不准确。这不是重点。由于好奇,我对以下行为的原因感兴趣。
我正在通过setInterval
或setTimeout
安排一个函数来运行每x ms。我还测量了ms精度实际经过的时间。这是代码:
var counter = 0;
var start = Date.now();
var last = start;
var now;
var step = 10;
var tick = function () {
now = Date.now();
console.log(counter++, now, now - last);
last = now;
if (counter > 10) {
clearInterval(tick);
}
};
setInterval(tick, step);
Ubuntu 15.04(3.19.0-15-generic)上Node.js 4.0.0的输出如下:
0 1442445968559 11
1 1442445968597 38
2 1442445968611 14
3 1442445968621 10
4 1442445968632 11
5 1442445968641 9
6 1442445968651 10
7 1442445968661 10
8 1442445968672 11
9 1442445968683 11
我可以看到大多数呼叫的1到2毫秒的不准确性。有趣的是第二条线在28毫秒后关闭。
相同的实验延迟100毫秒:
0 1442446176790 100
1 1442446176940 150
2 1442446177044 104
3 1442446177145 101
4 1442446177245 100
5 1442446177345 100
6 1442446177446 101
7 1442446177546 100
8 1442446177646 100
9 1442446177747 101
再次,第二行脱颖而出。
使用process.nextTick
:
var counter = 0;
var start = Date.now();
var last = start;
var now;
var step = 10;
var check = function () {
now = Date.now();
if (now >= last + step) {
tick();
}
if (counter < 10) {
process.nextTick(check);
}
};
var tick = function () {
console.log(counter++, now, now - last);
last = now;
};
process.nextTick(check);
结果是:
0 1442446399599 10
1 1442446399620 21
2 1442446399630 10
3 1442446399640 10
4 1442446399650 10
5 1442446399660 10
6 1442446399670 10
7 1442446399680 10
8 1442446399690 10
9 1442446399700 10
现在除了第二个电话之外的所有电话都很完美。
任何人都可以解释原因吗?我想这是必须在系统级别处理的事情。
答案 0 :(得分:1)
这是因为console.log()
。由于console.log
在第一次通话期间占用更多的CPU时间,第二个操作将花费更长的时间。 (警告:这是一个有根据的猜测)
var counter = 0;
var start = Date.now();
var last = start;
var now;
var step = 10;
var data = [];
var tick = function () {
now = Date.now();
var time = now - last;
last = now;
counter++;
data.push(counter + " " + now +" "+time);
if (counter > 10) {
clearInterval(interval);
console.log(data.join('\n'));
}
};
var interval = setInterval(tick, step);
结果:
1 1442450286606 12
2 1442450286617 11
3 1442450286627 10
4 1442450286637 10
5 1442450286648 11
6 1442450286658 10
7 1442450286668 10
8 1442450286678 10
9 1442450286688 10
10 1442450286698 10
11 1442450286708 10
编辑 - 使用cpu处理修改上述内容会给我的假设增加一点额外的重量。
var counter = 0;
var start = Date.now();
var last = start;
var now;
var step = 10;
var data = [];
var tick = function () {
now = Date.now();
var time = now - last;
last = now;
counter++;
data.push(counter + " " + now +" "+time);
if (counter == 4){
for (var i=0;i<10000000;i++){
//waste some time
}
}
if (counter > 10) {
clearInterval(interval);
console.log(data.join('\n'));
}
};
var interval = setInterval(tick, step);
结果显示在使cpu更繁忙之后时间增加:
1 1442451041828 12
2 1442451041838 10
3 1442451041849 11
4 1442451041860 11
5 1442451041902 42
6 1442451041914 12
7 1442451041924 10
8 1442451041934 10
9 1442451041944 10
10 1442451041954 10
11 1442451041964 10