Javascript setTimeout в foreach: нужна помощь в создании закрытия

У меня есть эта функция

notes.forEach(function(note) {          
    setTimeout(function() {
        playNote(note);
    }, 1000);
});

Это не сработает. Он воспроизводит все ноты одновременно, вместо того, чтобы воспроизводить их последовательно с 1-секундным промежутком между ними. Похоже, мне нужно закончить здесь, чтобы это сработало. Может ли кто-нибудь помочь мне исправить эту функцию, чтобы она воспроизводила ноту с задержкой между каждой нотой?

3 ответов


потому что все тайм-ауты устанавливаются одновременно...

сделать что-то вроде этого:

playAllNotes(0);
function playAllNotes(index) {
    if(notes.length > index) {
        setTimeout(function() {
            playNote(notes[index]);
            playAllNotes(++index);
        }, 1000);
    }
}

есть два способа сделать это:

1) Есть функция, которая берет одну ноту каждую секунду, пока больше нет Примечания:

var interval = setInterval(function() {
  playNote(notes.shift()); // changes the notes array!
  if (!notes.length) clearInterval(interval);
}, 1000);

2) запустить все таймеры одновременно с разными задержками:

notes.forEach(function(note, index) {
  setTimeout(playNote.bind(null, note), index*1000);
});

вы можете использовать счетчик, это сложно, но стоит того, если вы работаете с объектами:

counter = 0;
$.each(object, function(index,item){
  counter++;
  var localCounter = counter;
  setTimeout(function{
   console.log('something')
  }, counter * 1000) // change one to number of milliseconds you need
})

первый счетчик является глобальным, поэтому, если мы не пользователь var localCounter мы будем выполнять все тайм-ауты одновременно.