使用 settimeout 执行慢速移动的脚本未按预期工作

Script to perform slow movement with settimeout not working as expected

我正在编写一个脚本来在一个元素中创建缓慢的移动,但它的表现不如我预期。我正在使用 settimeout 来延迟操作,但现在它迭代超过了 5 steps 的限制,我不确定为什么。感谢观看!

var step;
var steps = 5;

function init() {
 step = 0;
}

function render() {
  if (step < steps) {

    console.log("yo!");
    setTimeout(stepIncrease, 3000);
    console.log("steps:");
    console.log(steps);
  }
  requestAnimationFrame(render);
}

function stepIncrease() {
    step++;
    console.log("step:");
    console.log(step);
}

init();
render();

requestAnimationFrame() 表示您在 window 的下一次重绘之前请求 window 到 运行 函数。 setTimeout() 将在不同的队列中使用超时。

因此,由于您的渲染函数包含 requestAnimationFrame(render);,您基本上告诉计算机:do this function on every frame。所以你基本上在这里创建了一个无限循环,setTimeout()ed 函数永远不会 运行 增加计步器。

var step;
var steps = 5;

function init() {
 step = 0;
}

function render() {
  console.log("steps:");
  console.log(step);
  if (step < steps) {
    step++;
    console.log("yo!");
    setTimeout(render, 3000);
  }
}
init();
render();

延迟动作requestAnimationFrame应该是这样的

let step = 0;
let steps = 5;

const stepIncrease = () => {
    step++;
    requestAnimationFrame(render);
    console.log("step:", step);
}

function render() {
  if (step < steps) {

    console.log("yo!");
    setTimeout(stepIncrease, 3000);
    console.log("steps:", steps);
  }

}

render();

要了解实际情况,请看一下这个演讲What the heck is the event loop anyway? | Philip Roberts | JSConf

您滥用了带有 setTimeout 的 requestAnimationFrame。基本上 requestAnimationFrame 每秒被调用 60 次。因此,在执行 stepIncrease 之前(3 秒后),函数 render 已经执行了几次 setTimeout

我不确定你想要实现什么,但最简单的解决方案是将 requestAnimationFrame 移动到 stepIncrease() 函数内部。

var step;
var steps = 5;

function init() {
 step = 0;
}

function render() {
  if (step < steps) {

    console.log("yo!");
    setTimeout(stepIncrease, 3000);
    console.log("steps:");
    console.log(steps);
  }
}

function stepIncrease() {
    step++;
    console.log("step:");
    console.log(step);
    requestAnimationFrame(render);
}

init();
render();