骨干foreach等待

时间:2012-09-19 14:46:44

标签: javascript backbone.js

我有一个赛道模型和一系列曲目。模型本身具有播放单个轨道的功能播放()。当单曲目(按照列表的顺序)结束时,该集合应该能够播放每个曲目。

型号:

app.Track = Backbone.Model.extend({
    defaults: {...},
    initialize: {...},
    play: function(playlist) {
       if(finished && playlist) {
           Backbone.pubSub.trigger('finishedPlaybackLoadNext')
       } else {
           Backbone.pubSub.trigger('finishedPlayback')  
       }
    },
})

收集:

var TrackList = Backbone.Collection.extend({
    model: app.Track,
    nextOrder: function() {...},
    comparator: function( track ) {...},
    playAll: function() {
       this.models.forEach(function(item) {
          item.play(true); //true = play as playlist
       });
    }
})

正如预期的那样,forEach不会等到列表中的每个单独模型完成播放。我怎样才能实现这种等待?

编辑:我正在使用全局触发器/订阅者在不同视图中分享事件。

Backbone.pubSub = _.extend({}, Backbone.Events);

1 个答案:

答案 0 :(得分:1)

我认为你应该有两个模型用于连续播放歌曲。首先你有一个Track模型及其相应的TrackList集合,但是你会有另一个名为PlayList的模型和一个集合。

Track的播放功能应该采用另一个参数,该参数将是Track完成播放时必须执行的回调。通过这种方式你也可以在PlayList上有一个播放功能,这个功能可以通过嵌套的回调连续播放所有歌曲(听起来像递归乐趣:P)。

编辑:我继续攻击我正在考虑的一些小实现。我不是在这里使用Backbone,但是我确信你可以调整这个想法,如果你有一些将回调函数传递给Songs play函数的话(顺便说一下......你怎么实际播放你的歌曲?)

Song = function(name) {
  var play = function() {
    console.log(name);
    sleep(1000);
  };

  this.name = name;
  this.play = function(cb) {
    play();
    if (typeof cb == "function") {
      cb.call(this);
    }
  };
};

PlayList = function(songs) {
  this.play = function(cb) {
    // define a function that calls the first song with a callback 
    // that calls the next song with a callback that calls the next
    // ... untill the last songs play function gets called with cb 
    // (parameter top this function) as the callback.
    var playFirstSong = _.reduce(songs.reverse(), function(cb, song) { 
      return function() {
        song.play(cb);
      };
    }, cb);

    playFirstSong();
  };
};

我也提出了jsFiddle