首页 > 解决方案 > 如何在javascript中制作准确的延迟函数

问题描述

我正在制作音乐作曲家并播放音符,我正在等待播放下一个音符之前的时间(以毫秒为单位)过去,我已经看到这似乎非常不准确,有时高达 10 毫秒的不准确,是否存在一种方法可以使更准确的超时或延迟功能降低到 0/1 毫秒的差异?我目前的代码是:

function delayMs(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

使用“tick”功能:

        while (this.state.isPlaying) {
            const { song, settings } = this.state
            let msPerBPM = Math.floor(60000 / settings.bpm.value)
            await delayMs(msPerBPM)
            this.handleTick()
        }

我可以使用服务人员,因为我注意到我遇到了这个问题,因为反应中的重新渲染延迟。

标签: javascriptreactjstime

解决方案


很容易证明使用setTimeout(并通过扩展setInterval)您永远不会获得毫秒精度。

下面演示了即使告诉 javascript 在 1 毫秒内执行,它也可以在几毫秒到几十毫秒后实际进行调用。

function recall(count){
  console.log(new Date())
  if(++count<10)
    setTimeout(recall,1,count);
}

recall(1)

你可能有更多的运气,requestAnimationFrame但你需要计算自上一步以来已经过去了多长时间,并用它来“同步”你想做的任何事情:

let start;

function step(timestamp) {
  if (start === undefined)
    start = timestamp;
  const elapsed = timestamp - start;

  console.log(elapsed);
  
  if (elapsed < 500) { // Stop the animation after 0.5 seconds
    window.requestAnimationFrame(step);
  }
}

window.requestAnimationFrame(step);


推荐阅读