簡體   English   中英

Javascript foreach循環轉到回調的下一個元素

[英]Javascript foreach loop go to next element on callback

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;
}

這是用於音樂播放系統。 LoadNavALoadNavB函數將軌道異步加載到播放列表。 這些元素必須以正確的順序排列。 當軌道3的加載早於軌道2的加載時,它首先放置軌道3和軌道2,但是在軌道1和2已經加載時,它應該開始加載軌道3。

調用LoadNavALoadNavB的回調時,循環應繼續進行。 怎么樣?

您面臨的問題是LoadNavALoadNavB調用異步操作,該操作可以按任何順序返回,但是您正在嘗試強制執行某些順序。 這是一個問題,因為您的循環將在實際執行回調時完成,因此您試圖延緩處理的嘗試被誤導了。

相反,您想要的是一種按順序調用一些異步操作的方法。 我編寫了一個通用函數來完成此任務:

// 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);
} 

該函數假定您要給它提供回調,該回調將執行一些操作,並且一旦完成,該操作將啟動鏈中的下一步。 為了更具體,這里是一個基於您的代碼的示例。

首先,進行一些設置,以便我們可以使用您的示例:

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

現在, 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();
        });
    }

});

作為loop的第二個參數給出的回調將對列表中的每個元素執行一次。 它接收播放列表中的一個元素和一個稱為next的函數作為參數。 該回調可以自由執行任何異步操作,只要這些操作一旦完成就調用next函數即可。 這是我們前進到播放列表中下一個元素的機制,因此可以對每個元素重復該過程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM