JS程序中secondsPassed与timePassed相加结果为NaN是什么原因?
问题原因
- 你第一次调用
gameLoop是通过setTimeout(gameLoop, 100)触发的,setTimeout执行回调时不会自动传入时间戳参数,因此第一次执行gameLoop时,形参timeStamp的值是undefined - 执行
secondsPassed = (timeStamp - oldTimeStamp) / 1000时,undefined参与数值运算会直接得到NaN,后续将NaN累加到timePassed上,结果自然也是NaN - 虽然后续通过
window.requestAnimationFrame调用gameLoop时会传入正确的时间戳,但第一次执行已经把timePassed污染为NaN,后续所有和NaN的运算结果都会保持为NaN
解决方法
你可以选择两种修改方案:
方案1:首次调用改用requestAnimationFrame触发
把setTimeout(gameLoop, 100);替换为window.requestAnimationFrame(gameLoop);即可,requestAnimationFrame触发的回调会自动传入高精度的时间戳参数,不会出现首次参数为空的问题。
方案2:给timeStamp参数添加兜底逻辑
在gameLoop函数开头添加参数校验,没有拿到有效时间戳时用当前时间兜底,修改后代码如下:
function gameLoop(timeStamp){ // 新增参数兜底逻辑 timeStamp = timeStamp || performance.now(); // 原有逻辑保持不变 secondsPassed = (timeStamp - oldTimeStamp) / 1000; oldTimeStamp = timeStamp; secondsPassed = Math.min(secondsPassed, 0.1); fps = Math.round(1 / secondsPassed); update(secondsPassed); window.requestAnimationFrame(gameLoop); }
内容的提问来源于stack exchange,提问作者Mr.Skalman
相关产品推荐
相关产品推荐

