JS中的计时器(setTimeout/setInterval)并不精确,主要有以下原因:
JS是单线程的,计时器需要等待主线程空闲才能执行:
// 示例:实际间隔可能大于1000ms setInterval(() => { console.log('执行时间可能不准'); // 如果这里有耗时操作,会影响下一次执行时间 }, 1000);
最小延迟限制:浏览器通常限制最小延迟为4ms左右:
// 即使设置0ms,实际也会有约4ms延迟 setTimeout(() => { console.log('有最小延迟'); }, 0);
更精确的计时方案:
使用Date或performance.now()计算实际时间差:
const start = performance.now(); const interval = 1000; // 目标间隔1秒 function accurateTimer() { const drift = performance.now() - start - count * interval; count++; setTimeout(accurateTimer, interval - drift); }
使用requestAnimationFrame实现高精度动画:
let lastTime = 0; function animate(currentTime) { if (currentTime - lastTime >= 16.7) { // 60fps // 执行动画 lastTime = currentTime; } requestAnimationFrame(animate); } requestAnimationFrame(animate);Web Worker中的计时器:```javascript// worker.jslet count = 0;setInterval(() => {count++;postMessage(count);}, 1000);
// main.jsconst worker = new Worker('worker.js');worker.onmessage = (e) => { console.log(e.data);};
5. 节流控制示例: ```javascript function throttle(fn, interval) { let lastTime = 0; return function(...args) { const now = Date.now(); if (now - lastTime >= interval) { fn.apply(this, args); lastTime = now; } }; } const throttled = throttle(() => { console.log('执行'); }, 1000);
改进精度的建议:
使用performance.now()代替Date.now()获取更高精度时间戳
补偿误差:
class PreciseTimer { constructor(callback, interval) { this.callback = callback; this.interval = interval; this.expected = Date.now() + interval; this.timeout = null; this.start(); } start() { const drift = Date.now() - this.expected; this.callback(); this.expected += this.interval; this.timeout = setTimeout(() => this.start(), Math.max(0, this.interval - drift)); } stop() { clearTimeout(this.timeout); } }
使用Web Worker避免主线程阻塞
避免在计时器回调中执行耗时操作
网友回复
openai发布的agentkit与coze扣子、dify等流程搭建智能体有啥不同?
阿里云上的ecs镜像存储还要钱,如何免费下载到本地以后再创建?
如何通过调用大模型api实现输入一个商品图片生成模特展示解说的宣传短片?
qwen千问大模型api如何内置互联网搜索?
YOLO如何结合opencv实现视觉实时摔倒检测?
html中内嵌style与link引入css代码报错的处理机制不同?
coze扣子中调用seadream4多参考图修改ps图片如何返回图片尺寸设为第一个图片的尺寸?
coze扣子中如何将原图缩放到指定尺寸?
如何解决传大文件突然断网重传的问题?
CefSharp与Electron开发桌面应用哪个更好?