JavaScript快捷手册
测试耗时的回调动作是否影响setInterval的执行间隔,测试详情见下方代码及输出。
结论:
1. 触发间隔是相对于上一次触发时间而不是执行结束时间,所以回调耗时不会导致触发间隔上涨;
2. 当回调执行时间超过了下次触发时间,那么下一次回调会立即被触发;
3. 未能及时触发的多次回调并不会积压在队列中,也就是说及时回调耗时恢复到很低,也不会把之前“拖欠”的回调全部执行一遍;所以如果是游戏类的应用,不可以依赖setInterval去自动补回前面延迟的帧数。
1. 回调耗时不是特别长的情况
>> a = setInterval(()=>{console.log('S:' + Date.now()); for(i=1000000;i>0;i--){j=Math.asin(i)}; console.log('E:' + Date.now());}, 1000)
1
S:1588525294181
E:1588525294244
S:1588525295181
E:1588525295234
S:1588525296185
E:1588525296225
S:1588525297182
E:1588525297234
clearInterval(a)
2. 回调耗时超过间隔的情况:
>> k=3; a = setInterval(()=>{console.log('S:' + Date.now()); for(i=100000000;i>0;i--){j=Math.asin(i)}; console.log('E:' + Date.now()); k=k-1; if(k<=0){clearInterval(a); console.log('clear');}}, 1000)
2
S:1588525767204
E:1588525769016
S:1588525769017
E:1588525770812
S:1588525770815
E:1588525772721
clear
3. 回调耗时超过间隔是否积压:
>> loop=100000000; k=0; a = setInterval(()=>{console.log('S'+k+':' + Date.now()); for(i=loop;i>0;i--){j=Math.asin(i)}; console.log('E'+k+':' + Date.now()); k++; if(k >= 5) loop = 0;}, 1000); setTimeout(()=>{clearInterval(a); console.log('clear:' + Date.now());},11800);
3
S0:1588527004327
E0:1588527007372
S1:1588527007373
E1:1588527009176
S2:1588527009179
E2:1588527011046
S3:1588527011046
E3:1588527012940
S4:1588527012941
E4:1588527014825
S5:1588527014825
E5:1588527014825
clear:1588527015127

浙公网安备 33010602011771号