最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript setTimeout in foreach: need help creating a closure - Stack Overflow

programmeradmin2浏览0评论

I have this function

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

This doesn't work. It plays all the notes at the same time, instead of playing them sequentially with a 1 second gap in between. It looks like I need to have a closure here to make this work. Could someone help me fix this function so it would play the note with the delay between each note?

I have this function

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

This doesn't work. It plays all the notes at the same time, instead of playing them sequentially with a 1 second gap in between. It looks like I need to have a closure here to make this work. Could someone help me fix this function so it would play the note with the delay between each note?

Share Improve this question asked Feb 20, 2014 at 10:17 PrabhuPrabhu 13.3k34 gold badges133 silver badges214 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 12

There are two ways to do this:

1) Have a function that grabs one note every second until there are no more notes:

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

2) Start all the timers at the same time with different delays:

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

because all timeouts are set at the same time...

Do something like this:

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

You can use a counter, it's tricky but worth it if you are working with objects:

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

First counter is global, so if we don't user var localCounter we would execute all timeouts at the same time.

发布评论

评论列表(0)

  1. 暂无评论