2012-09-19 43 views
0

我有一个轨道模型和轨道集合。该模型本身具有播放单曲的功能play()。当单个轨道(按列表顺序)完成时,该集合应该能够逐一播放每个轨道。骨干foreach等待

型号:

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

我觉得你应该有两种模式来连续播放歌曲。首先你有一个Track模型和它相应的TrackList集合,但是你会有另一个称为PlayList的模型和一个集合。

Track的播放函数应该接受另一个参数,这个参数是Track完成播放时必须执行的回调。通过这种方式,您也可以在PlayList上播放一个播放功能,并且此功能可以处理通过嵌套回调播放所有歌曲(听起来像递归的乐趣:P)。

编辑:我继续前进,并且破解了我所想的一些小实现。我在这里没有使用Backbone,但是我相信你可以适应这个想法,如果你有一些回调函数传递给歌曲播放功能的话(顺便说一下......你是怎么演奏你的歌曲的?) 。

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也是这样。