首页 > 解决方案 > 有没有办法让代码执行暂停 1 毫秒?我现在能做的最好是5ms左右

问题描述

有没有办法让代码执行暂停 1 毫秒?我现在能做的最好的事情是大约 5 毫秒,我正在制作一个排序可视化器来练习。我开始使用 div 来表示正在排序的数组的值,但在大型数组上似乎很慢,所以我切换到画布。但现在我的瓶颈是我用来暂停代码的这个函数,以便数组上的更改实际上是可见的,否则它是如此之快以至于它只是在按钮单击时排序。下面是我用来测试暂停功能(我在我的可视化器中使用的)的内容,看看它是否真的是 1ms,因为它感觉不像。

const number = 100
const delay = 1

const pause = () => new Promise((res) => setTimeout(res, delay));

async function testPause() {
  for (let i = 0; i < number; i++){
    console.time("pause")
    await pause()
    console.timeEnd("pause")
  }
}

testPause()

对于 delay >= 4 可以正常工作。控制台显示 4 +- 0.5ms 的值。但低于 4 它显示与 4 相同的值。即使延迟 = 0。有没有更好的方法来做到这一点?

标签: javascriptpause

解决方案


由于您的最终目标是创建动画,因此您只需将“nextAnimationStep”函数调用两次或三次即可。最终用户不应该注意到任何卡顿,因为帧速率应该足够高以保持它看起来流畅。

这是一个动画运行太慢的示例:

const squareEl = document.getElementById('square')
let x = 0

function runNextAnimationStep() {
  squareEl.style.left = x++ + 'px'
  return x > 150
}

async function step() {
  const complete = runNextAnimationStep()
  if (!complete) {
    requestAnimationFrame(step)
  }
}
step()
#square {
  width: 32px;
  height: 32px;
  background: blue;
  position: absolute;
}
<div id="square"></div>

以下是我们在不修改 runNextAnimationStep() 的情况下加快速度的方法:

const squareEl = document.getElementById('square')
let x = 0

function runNextAnimationStep() {
  squareEl.style.left = x++ + 'px'
  return x > 150
}

async function step() {
  let complete = false
  for (let i = 0; i < 3 && !complete; ++i) {
    complete = runNextAnimationStep()
  }
  if (!complete) {
    requestAnimationFrame(step)
  }
}
step()
#square {
  width: 32px;
  height: 32px;
  background: blue;
  position: absolute;
}
<div id="square"></div>

请注意,上述蛮力解决方案将根据 requestAnimationFrame() 触发的速度提供不同的动画速度。为了使其运行更加一致,您需要确定所需的帧速率,并使用 requestAnimationFrame() 提供给回调的DOMHighResolutionTimestamp自动调整调用函数的频率以便平均调用该函数每秒执行相同的次数。runNextAnimationStep()


推荐阅读