for(var P in ReturnData.Playlist){
var IsLoaded = false;
if(PlayerName == "A"){
LoadNavA(false,false,false, ReturnData.Playlist[P], function(){
IsLoaded = true;
alert();
});
}else{
LoadNavB(false,false,false, ReturnData.Playlist[P],function(){
IsLoaded = true;
});
}
if(IsLoaded == true) continue;
}
This is for a music playout system. The LoadNavA
and LoadNavB
functions load a track to the playlist asynchronously. These elements must be in the correct order. When track 3 is loaded earlier than track 2, it first places track 3 and than track 2, but it should start loading track 3 when track 1 and 2 are already loaded.
When the callback in LoadNavA
or LoadNavB
is called, then the loop should go on. How?
The problem you're facing is that LoadNavA
and LoadNavB
invoke asynchronous operations, which can return in any order, but you're attempting to enforce some ordering. This is a problem, because your loop will have completed by the time the callbacks are actually executed, so your attempts to hold-up the processing are misguided.
What you want, instead, is a means to invoke some asynchronous operations in order. I've written a general function to accomplish this:
// receives a callback and the elements to iterate
function loop(list, fn) {
if (!list || list.length <= 0)
return;
(function chain(i) {
if (i >= list.length)
return;
fn(list[i], function() {
chain(i + 1);
});
})(0);
}
This function assumes you're giving it a callback that will perform some operation and that that operation will kick-off the next step in the chain once it completes. To make this concrete, here is an example based off of your code.
First, a little setup, so that we can work with your example:
var PlayerName = "B";
var ReturnData = {};
ReturnData.Playlist = ["song1", "song2", "song3"];
function LoadNavA(b1, b2, b3, el, fn) {
// this could be any asynchronous call (e.g. Ajax)
// using setTimeout here for illustration
window.setTimeout(fn, 2000);
}
var LoadNavB = LoadNavA; // for brevity
Now, the actual usage of loop
:
loop(ReturnData.Playlist, function(song, next) {
if (PlayerName == "A") {
LoadNavA(false, false, false, song, function() {
alert("LoadNavA: " + song);
next();
});
} else {
LoadNavB(false, false, false, song, function() {
alert("LoadNavB: " + song);
next();
});
}
});
The callback given as the second argument to loop
will be executed once for each element in the list. It receives as arguments an element in the playlist and a function referred to as next
. This callback is free to execute any asynchronous operations, as long as those operations invoke the next
function once they're done. This is the mechanism by which we advance to the next element in the playlist so that the process can be repeated for every element.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.