#javascript #jquery #settimeout
Вопрос:
Я создаю игру «Саймон говорит» http://codepen.io/meek/pen/adrbOv используя jquery, и у меня возникли некоторые проблемы с воспроизведением каждого звука по одному.
Когда игра начинается, генерируется список из 20 звуков («ходов»), которые будут воспроизводиться один за другим каждый ход. Поэтому, если список ходов [ «красный», «желтый», «зеленый»], на первом ходу будет играть «красный», на втором — «красный» и «желтый» и так далее.
Я установил поворот на 4 и пытаюсь заставить каждый звук воспроизводиться один за другим, пока не будут воспроизведены 4 звука. Я использую этот код:
turn = 4;
var t = 1;
while(t <= turn) {
setTimeout(AIbutton(allMoves[t-1]), 1000);
t ;
}
AIbutton()
это функция, которая воспроизводит звук (имитирует нажатие кнопки) и allMoves
представляет собой список из 20 ходов, которые будут воспроизводиться на протяжении всей игры. Я хочу, чтобы это произошло, чтобы звук воспроизводился на каждой итерации цикла, прежде чем переходить к следующей итерации, но происходит то, что все звуки в цикле воспроизводятся одновременно после интервала в 1000 мс.
Я думал, что setTimeout сделает это так, чтобы он делал паузы между итерациями? Как я могу этого достичь?
Ответ №1:
setTimeout выполняется асинхронно, он не блокируется. Если вы хотите дождаться окончания тайм-аута, следующая «итерация цикла» должна произойти в обратном вызове функции, которую вы задаете setTimeout.
Что-то вроде этого сработало бы:
turn = 4;
var t = 1;
ourTimeout(allMovies, turn, t);
function ourTimeout(allMovies, turn, t){
AIbutton(allMoves[t-1]);
if(t <= turn)
setTimeout(ourTimeout(allMovies, turn, t), 1000);
}
@Alnitak упоминает, что эта строка кода:
setTimeout(ourTimeout(allMovies, turn, t), 1000);`
необходимо изменить на это:
setTimeout(function(){
ourTimeout(allMovies, turn, t);
}, 1000);
Как утверждает @Alnitak, вы можете передать в setTimeout только анонимную или именованную функцию. Трюк с передачей переменных выполняется так, как указано выше (концепция называется закрытием).
Комментарии:
1. этот код неверен — вам нужно передать ссылку на функцию
setTimeout
(например, анонимное выражение функции), а не результат вызоваourTimeout
.2. Это делает именно то, что мне нужно, и теперь я понимаю, почему. Спасибо!