0

我有一个轨道模型和一组轨道。模型本身有一个播放单个曲目的函数 play()。当单个曲目(按列表顺序)完成时,该集合应该能够逐个播放每个曲目。

模型:

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);
4

1 回答 1

1

我认为你应该有两个模型来连续播放歌曲。首先,您有一个 Track 模型及其对应的 TrackList 集合,然后您将有另一个称为 PlayList 的模型和一个集合。

然后,Track 的播放函数应采用另一个参数,该参数是在 Track 播放完毕时必须执行的回调。这样,您也可以在 PlayList 上具有播放功能,并且该功能将通过嵌套回调处理连续播放所有歌曲(听起来像递归乐趣:P)。

编辑:我继续并破解了我所想的一些小实现。我在这里没有使用 Backbone,但我相信你可以适应这个想法,如果你有一些将回调函数传递给 Songs 播放函数的想法(顺便说一句......你实际上是如何播放你的歌曲的?) .

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

于 2012-09-19T15:00:59.963 回答