10

この質問が何度も尋ねられたことは知っていますが、私の場合、この回答を機能させる方法を一生理解できません。非同期のJavaScript関数が戻るのを待ちます

外側のループでいくつかの「テレビ チャンネル」をループしてから、内側のループでその週の日付をループしています。内側のループでは、サーバーに ajax リクエストを送信してデータを取得し、後で使用するために保存/キャッシュします。

var dates = []; //<-- Contains a list of dates for the coming week 
var baseUrl = "http://www.someserver.com";
var storedChannels = [1,2,3,4,5,6,7,8,9,10,45,23,56,34,23,67,23,567,234,67,345,465,67,34];

for(ch = 0; ch < storedChannels.length; ch++) {   
    var channel = storedChannels[ch];
    for(d=0; d < 7; d++) {
        var currentDate = dates[d];
        ajax({    
            url: baseUrl+"?ch="+channel+"&dt=currentDate"+,
            complete: function(res) {
                CMLocalStore.setString('ch' + ch + "_" + scheduleDay, res);
            },
        });
        //Want to wait here till the ajax request completes.
        //Do not want to continue to next iteration.
        //Do not want to fire of 50 bazillion ajax requests all at once
        //Why? Very limited bandwidth scenario, plenty of channels  
    }
}

PS: JQuery は使用しないでください。プレーン JS ソリューションのみ

どうもありがとう!

4

5 に答える 5

18

あなたはこのようなものが欲しいです。私はそれをテストしていませんが、うまくいけば、あなたはその考えを理解するはずです.

var dates = []; //<-- Contains a list of dates for the coming week 
var baseUrl = "http://www.someserver.com";
var storedChannels = [1,2,3,4,5,6,7,8,9,10,45,23,56,34,23,67,23,567,234,67,345,465,67,34];

function ProcessNext(ch, d) {
    if (d < 7) {
        d++;
    } else {
        d=0;
        if (ch < storedChannels.length) {
            ch++;
        } else {
            return;
        }
    }

    var channel = storedChannels[ch];
    var currentDate = dates[d];
    ajax({    
        url: baseUrl+"?ch="+channel+"&dt=currentDate"+,
        complete: function(res) {
            CMLocalStore.setString('ch' + ch + "_" + scheduleDay, res);
            ProcessNext(ch, d);
            },
    });
}

ProcessNext(0, 0);
于 2011-02-21T12:45:30.693 に答える
4

ループを一連のコールバックに変える必要があります。

ループを使用する代わりに、コールバックで元の関数を呼び出す必要がありますが、パラメーター値は高くなります。

于 2011-02-21T12:40:30.810 に答える
1

基本的に、答えはループを使用する代わりに再帰呼び出しを使用することにあります。2 レベルよりも深い「for ループの入れ子」に興味がある人のために、この回答を追加したかっただけです。ご覧のとおり、好きなだけ「入れ子」に簡単に拡張できます。元の功績は、DaniWeb フォーラムの Java でのVatooVatoo実装にあります。

テスト済みで動作するコードは次のとおりです (もちろん ajax ビットはありませんが、自分で追加できます)。

<html>
<head>
<script type="text/javascript">
    function loopRecurse(a, b, c)
    {
        if(c >= 2) {
            b++;
            c=0;
            loopRecurse(a, b, c);
            return;
        }
        if(b >= 2) {
            a++;
            b=0;
            loopRecurse(a, b, c);
            return;
        }
        if(a >= 2) return;
        document.write("<div>" + a + "|" + b + "|" + c + "</div>");
        c++;
        loopRecurse(a, b, c);
    }
    loopRecurse(0, 0, 0);
</script>
</head>
<body>
    <!-- output
        0|0|0
        0|0|1
        0|1|0
        0|1|1
        1|0|0
        1|0|1
        1|1|0
        1|1|1
     -->
</body>
</html>
于 2011-02-23T13:34:38.450 に答える
1

あなたがやろうとしていることは、Pedro Teixeira によるAsynchronous Iteration Patternsチュートリアルで説明されています。例では Node.js を使用していますが、ブラウザーでも同じパターンを使用できます。基本的に必要なことは、ループを相互に完了するのを待つシリアル コールバックに変換することです。そのため、次の AJAX リクエストは前の成功コールバックから起動されます。ブラウザをブロックせずに実行できますが、ループでは実行できません。そのチュートリアルを参照してください。

于 2011-02-21T12:55:07.557 に答える
-2

XMLHttpRequest のドキュメントを参照してください(MDC にリンクされていますが、重要ではありません)。基本的に、あなたが探している条件は、実際のオブジェクトを返すrequest.readyState==4ことを前提としています。ajax()XMLHttpRequest

于 2011-02-21T12:41:07.957 に答える