setTimeout не работает внутри EventListener - PullRequest
0 голосов
/ 09 октября 2018

Я делал простую программу, которая имитирует кого-то, бросающего объект.Кажется, все работает, но ... я хочу выполнить один цикл в течение ~ 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 - это координаты вектора, полученные путем вычитания координат из EventListener "mouseup" из координат из события "mousedown".Bob_x - это x-координата блока, представляющего парня.

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Ваш цикл for работает синхронно, устанавливая кучу тайм-аутов, каждый из которых будет происходить через 100 мс после окончания цикла for.Если вы хотите дождаться завершения каждой функции, прежде чем переходить к следующей итерации, вам потребуется другая стратегия, например await a 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));
  }
})
0 голосов
/ 09 октября 2018

Он не ждет и выполняет все примерно за четверть секунды.

Десятая, фактически (100 мс).

Основная проблема заключается в том, что вы планируетегруппа таймеров, которые все сработают через 100 мс.Если вы хотите, чтобы они делались с интервалами 100 мс, вам нужно увеличить тайм-аут 100 мс для последующих таймеров, например, умножив 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_x иpos_y не объявлены в обработчике.

Если это для анимации, вы, вероятно, захотите использовать requestAnimationFrame для этого. Вот статья Пола Айриша , которая может быть полезной.

...