Reputation: 5410
I've got a track model and a collection of tracks. The model itself has a function play() that plays a single track. The collection should be able to play each track after another when the single track (in order of the list) is finished.
Model:
app.Track = Backbone.Model.extend({
defaults: {...},
initialize: {...},
play: function(playlist) {
if(finished && playlist) {
Backbone.pubSub.trigger('finishedPlaybackLoadNext')
} else {
Backbone.pubSub.trigger('finishedPlayback')
}
},
})
Collection:
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
});
}
})
As expected the forEach does not wait till play is done for each individual model in the list. How can I achieve this kind of waiting?
Edit: I am using a global trigger/subscriber for events to share them within different views.
Backbone.pubSub = _.extend({}, Backbone.Events);
Upvotes: 0
Views: 354
Reputation: 6418
I think you should have two models for the purpose of playing songs in a row. First you have a Track model and its corresponding TrackList collection, but then you would have another model called PlayList and a collection for that too.
The Track's play function should then take another parameter which would be a callback that has to be executed when the Track has finished playing. in this way you could have a play function on a PlayList too and this function would take care of playing all songs in a row through nested callbacks (sounds like recursive fun :P).
edit: I went ahead and hacked some small implementation of what I was thinking of. I'm not using Backbone here, but i'm sure you could adapt the idea, if you have some waz of passing a callback function to the Songs play function (by the way... how are you actually playing your 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();
};
};
I made a jsFiddle out of this too.
Upvotes: 1