Создайте паузу в цикле while в JavaScript - PullRequest
22 голосов
/ 28 декабря 2010

Я хотел бы создать паузу внутри цикла while, чтобы я мог создавать n анимации, каждая из которых появляется через 3 секунды после другой.

Я пробовал следующее, но это не работает. Хотел бы, чтобы кто-то показал мне, что я делаю неправильно. Спасибо !!

i=0;
while (i < n) {
    someanimation();
    setTimeout(function(){
        i++;
    }, 3000);

};

Ответы [ 7 ]

36 голосов
/ 28 декабря 2010

setTimeout не останавливается; он просит Javascript запустить какой-то другой код позже.

Поиск в Google по "циклу setTimeout" говорит вам именно то, что вам нужно знать. Если немного осмотреться, в нем даже упоминается setInterval. Разница в том, что использование setTimeout для цикла будет ждать 3 секунды между циклами, тогда как setInterval заставит цикл занять 3 секунды (включая то, сколько времени занимает анимация, если она меньше 3 секунд :)). Кроме того, setInterval создает бесконечный цикл, из которого вам придется разорваться после желаемого количества раз; setTimeout требует, чтобы вы создали цикл самостоятельно.

i = 0;

function animation_loop() {
  someAnimation();
  setTimeout(function() {
    i++;
    if (i < n) {
      animation_loop();
    }
  }, 3000);
};
animation_loop();

i = 0;
someAnimation();
setInterval(function() {
  i++;
  if (i < n) {
    someAnimation();
  }
}, 3000);
11 голосов
/ 28 декабря 2010

setTimeout немного сложнее, потому что он не блокируется (т. Е. Он не заканчивает ожидание по таймауту, прежде чем продолжить работу с программой).

То, что вы хотите, ближе к этому:

var i = 0;
function nextFrame() {
    if(i < n) {
        someanimation();
        i++;
        // Continue the loop in 3s
        setTimeout(nextFrame, 3000);
    }
}
// Start the loop
setTimeout(nextFrame, 0);

Возможно, вам стоит прочитать setInterval в качестве возможной альтернативы.

3 голосов
/ 24 июня 2016

Один из способов сделать это - использовать RxJS.Пожалуйста, посмотрите на рабочий пример здесь

Rx.Observable
  .interval(1000)
  .take(10)
  .subscribe((x) => console.log(x))
2 голосов
/ 07 июня 2018

Что ж, благодаря ES6-7 с Promises мы теперь можем сделать паузу и сделать так, чтобы она выглядела одновременно!

var id = 0;

async function do() {
  while(true) {
    await pause(id);
    //will happen only after pause is done
    id++; 
  }
}
function pause(id) {
  return new Promise(resolve => setTimeout(() => {
    console.log(`pause ${id} is over`);
    resolve();
  }, 1500)); 
}

do();
0 голосов
/ 13 декабря 2014
function myFunction() {
    var x;
for(var i=0;i<10;i++){
    if (confirm("Press a button!") == true) {
        x = "You pressed OK!";
    } else {
        x = "You pressed Cancel!";
    }
    document.getElementById("demo").innerHTML = x;
}
}``
0 голосов
/ 28 декабря 2010

создайте такую ​​функцию, как:

function sleep_until (seconds) {
   var max_sec = new Date().getTime();
   while (new Date() < max_sec + seconds * 1000) {}
    return true;
}

, а затем измените код на

i=0;
while (i < n) {
    someanimation();
    sleep_until(3);
    do_someotheranimation();
};
0 голосов
/ 28 декабря 2010

Вы не очень конкретны в отношении того, что хотите сделать, но я бы сказал, что основная проблема заключается в том, что вы звоните someanimation() без задержки. Так что, возможно, это решит это для вас:

for (var i = 0; i < n; i++) {
    setTimeout(someanimation, 3000 * i);
};

Обратите внимание на пропущенный () после someanimation, поскольку это обратный вызов для setTimeout().

...