2014-02-20 9 views
8

Ich habe diese FunktionJavascript SetTimeout in foreach: Erstellen von Hilfe benötigen einen Verschluss

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

Dies funktioniert nicht. Es spielt alle Noten gleichzeitig ab, anstatt sie nacheinander mit einer Lücke von 1 Sekunde zu spielen. Es sieht so aus, als müsste ich hier eine Schließung haben, damit das funktioniert. Könnte jemand mir helfen, diese Funktion zu reparieren, so dass es die Note mit der Verzögerung zwischen jeder Note spielen würde?

Antwort

4

weil alle Timeouts zur gleichen Zeit eingestellt sind ...

etwas tun:

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

Frage ... das funktioniert, aber wenn ich eine andere Aktion zusammen mit playNote() hinzufügen, tut es nicht. Wenn ich zB class ('playing') vor playnote() und removeClass ('playing') nach playNote() anwende, spielt es alle Noten ab, aber die add/remove-Klasse passiert nur beim ersten Mal. Es funktioniert aber im Debugger ... irgendwelche Gedanken? – Prabhu

+0

Sie entfernen Klasse "spielen" von was? Ich habe keinen Code, um diesen Text zu verstehen. – Cracker0dks

+0

Egal, es zeigte und versteckte die CSS sehr schnell, um für das menschliche Auge wahrnehmbar zu sein, also fügte ich das in einem setTimeout hinzu und jetzt ist alles in Ordnung. Vielen Dank für Ihre Hilfe. – Prabhu

11

Es gibt zwei Möglichkeiten, dies zu tun:

1) eine Funktion haben, die Greift jede Sekunde eine Note, bis keine weiteren Notizen vorhanden sind:

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

2) Starten Sie alle Timer zur gleichen Zeit mit verschiedenen Verzögerungen:

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

Intelligente und interessante Lösungen. –

0

Sie einen Zähler verwenden kann, ist es schwierig, aber es lohnt sich, wenn Sie mit Objekten arbeiten:

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 
}) 

Der erste Zähler ist global, so dass, wenn wir don‘ t Benutzer var localCounter würden wir alle Timeouts gleichzeitig ausführen.