setTimeout在eventlistener中不起作用

问题描述 投票:1回答:2

我一直在做一个简单的程序,它可以模拟抛出物体的人。一切似乎都有效,但是...我想每100毫秒执行一个循环。

button.addEventListener("click", function(){

  for(let i = bob_x; i < 1504; i++){
    setTimeout(function(){
      pos_x = i;
      //console.log("vx: " + vx);
      //console.log("vy: " + vy);
      //console.log("i: " + i);
      //console.log("G: " + G);
      pos_y = vy/vx*i - G*i*i/2/vx/vx;

      obj.style.setProperty("left", pos_x);
      obj.style.setProperty("top", parseInt(pos_y, 10));
    }, 100)
  }
})

它不会等待并在大约四分之一秒内执行所有操作。我不知道为什么。

这里的vx和vy是矢量的坐标,通过从事件“mousedown”的坐标中减去eventlistener“mouseup”的坐标而得到。 Bob_x是表示人的块的x坐标。

javascript settimeout
2个回答
2
投票

你的for循环同步运行,设置了一堆超时,每个超时都会在for循环结束后100毫秒发生。如果你想在继续下一次迭代之前等待每个函数完成,你需要一个不同的策略,也许await在每次迭代时都是delay

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
button.addEventListener("click", async function(){

  for(let i = bob_x; i < 1504; i++){
    await delay(100);
    pos_x = i;
    //console.log("vx: " + vx);
    //console.log("vy: " + vy);
    //console.log("i: " + i);
    //console.log("G: " + G);
    pos_y = vy/vx*i - G*i*i/2/vx/vx;

    obj.style.setProperty("left", pos_x);
    obj.style.setProperty("top", parseInt(pos_y, 10));
  }
})

2
投票

它不会等待并在大约四分之一秒内执行所有操作。

十分之一,实际上(100毫秒)。

主要的问题是你要安排一堆计时器,这些计时器将在100毫秒后完成。如果你想要它们以100ms的间隔,你需要为后续的定时器延长100ms的超时时间,例如将100乘以i - bob_x + 1

button.addEventListener("click", function(){

  for(let i = bob_x; i < 1504; i++){
    setTimeout(function(){
      // ...
    }, 100 * (i - bob_x + 1)) // <============
  }
})

另外,奇怪的是pos_xpos_y没有在处理程序中声明。

如果这是出于动画目的,您可能希望使用requestAnimationFrameHere's an article by Paul Irish可能有用。

© www.soinside.com 2019 - 2024. All rights reserved.