在js中如果打算使用setInterval进行倒数,计时等功能,往往是不准确的,因为setInterval的回调函数并不是到时后立即执行,而是等系统计算资源空闲下来后才会执行.而下一次触发时间则是在setInterval回调函数执行完毕之后才开始计时,所以如果setInterval内执行的计算过于耗时,或者有其他耗时任务在执行,setInterval的计时会越来越不准,延迟很厉害.
下面的代码可以说明这个问题
|
1
2
3
4
5
6
7
8
9
10
11
|
var
startTime = new
Date().getTime();var
count = 0;//耗时任务setInterval(function(){ var
i = 0; while(i++ < 100000000);}, 0);setInterval(function(){ count++; console.log(new
Date().getTime() - (startTime + count * 1000));}, 1000); |
代码里输出了setInterval触发时间和应该正确触发时间的延迟毫秒数
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
1763404956528079611114126814251579173418882048220123572521267928342996
...... |
可以看到延迟是越来越严重的.
为了在js里可以使用相对准确的计时功能,我们可以
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
var
startTime = new
Date().getTime();var
count = 0;setInterval(function(){ var
i = 0; while(i++ < 100000000);}, 0);function
fixed() { count++; var
offset = new
Date().getTime() - (startTime + count * 1000); var
nextTime = 1000 - offset; if
(nextTime < 0) nextTime = 0; setTimeout(fixed, nextTime); console.log(new
Date().getTime() - (startTime + count * 1000));}setTimeout(fixed, 1000); |
代码里,通过1000(也就是周期时间)减去当前时间和准确时间的差距,来算出下次触发的时间,从而修正了当前触发的延迟.
下面是输出
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
186200230271158899900899900899899899902899418202232266145174192214242268149179214
...... |
可以看到虽然触发时间并非绝对准确,但由于每次触发都进行及时修正,所以并没有造成误差积累.
本文探讨了在JavaScript中使用setInterval进行倒数和计时功能时存在的准确性问题,并提出了一种通过实时修正触发延迟的方法来提高计时精度。通过分析代码示例,展示了如何通过减去当前时间和准确时间的差距来计算下次触发的时间,从而减少误差积累。
4113

被折叠的 条评论
为什么被折叠?



