7

同じ命名規則と構造を持つ3つの異なるjsonファイルのajax呼び出しをループしようとしています(ただし、データはわずかに異なります)。フォーラムで Alnitak の応答 ( jQuery ajax success callback function definition )を読んで以来、成功オプションの代わりに遅延オブジェクトを使用して、ajax 処理とコールバック処理を分離できるようにしています。以下は私のコードです:

<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=ISO-8859-1" />

<title>Stuff</title>
<script src="jquery-1.9.1.min.js" type="text/javascript"></script> 
</head>

<body>
<script Language="JavaScript">

    var myData = [];
    var myURL =  ["ticker1.json","ticker2.json","ticker3.json"];    //New Array for my URLs

    function getData(m) {

        return $.ajax({
            url : myURL[m],  //<<<---Want to loop through this array
            type : 'GET',
            dataType: 'json'
        });

    }

    function handleData(data){

        for (var i=0; i<data.test.msgOne.length; i++){
            myData[i] = data.test.msgOne[i];
        }

    };



    for (var j=0; j<3; j++){

        console.log(j);  //<<---First console statement
        var ajaxCall = getData(j).done(handleData);

        $.when(ajaxCall).done(function(){ //wait until the ajax call is done before writing

            console.log(j);  //<<---Second console statement

            for (var k=0; k<3; k++){
                document.write(myData[k])
                document.write('<br><br>');
            }

        });

    }

</script>
</body>
</html>

私のコードは、ajax 呼び出しを実行する getData という関数と、ajax 呼び出しから json ファイル内のデータを単純にループし、配列 myData にデータを格納する handleData という関数で構成されています。次に、for ループが配列 myData のデータを画面に出力しようとします。ただし、問題は、3 つすべてを順番に取得するのではなく、画面に出力された最初の json ファイルからのみデータを取得していることです。

そのため、for ループに 2 つの console.log ステートメントを入力しました。1 つは ajax 呼び出しの前、もう 1 つは ajax 呼び出しが完了した後でした。最初の console.log は予想どおり 0、1、2 を順番に出力し、2 番目は予想外の 3 を出力します。そのため、カウンターが終了する前に ajax 呼び出しが返されないと想定しました。for ループをいくつかのロジック ステートメントと while ループに置き換えました (はい、無期限に実行されるコードの危険性は承知しています)。

    var j=0;
    var whileFlag= new Boolean(1);
    var ajaxFlag = new Boolean(1);

    while (whileFlag) {

        if (ajaxFlag > 0) {
            ajaxFlag = 0;
            console.log(j);
            var ajaxCall = getData(j).done(handleData);
        }
        $.when(ajaxCall).done(function(){
            console.log(j);
            for (var k=0; k<3; k++){
                document.write(myData[k])
                document.write('<br><br>');
            }
            ajaxFlag = 1;
            j++;
        });

        if (j>=3) {whileFlag = 0};
    }

置換コードは、ajax 呼び出しを強制的に終了させ、次の ajax 呼び出しに移る前にコードを実行する試みでした。まあ、最終結果はフリーズしたブラウザで、ブエノではありませんでした。各jsonファイルのmyData配列を画面に書き込む方法を知っている人はいますか? ヘルプと建設的なコメントをいただければ幸いです。また、将来jsonpデータ型を扱う予定なので、ajax呼び出しを非同期に保つ必要があります。

追加の質問: ブラウザーがハングアップするのは ajax が呼び出しを返さないためだと思いますが、質問はなぜですか? 最初の例で for ループを実装しないことを選択し、代わりに j 変数を明示的に 0、1、または 2 に設定すると、選択した json ファイルのデータが正常に出力されますが、それ以上のことを行うと最初のjsonファイルからのデータセットのみを出力します。複数の ajax 呼び出しなどを実行できないようです。洞察と助けをいただければ幸いです。ありがとう。

4

3 に答える 3

2

問題は、 while ループが同等であることです...

 while (whileFlag) {

    if (ajaxFlag > 0) {
        ajaxFlag = 0;
        console.log(j);
        var ajaxCall = getData(j).done(handleData);
    }
    // Some thrid party (asynch Handler) changes j
    if (j>=3) {whileFlag = 0};
}

理想的には、Ajaxがコードを完了するまで、次のように実行されます

 while (whileFlag) {
  if (j>=3) {whileFlag = 0};
    }

ブラウザがハングします...

最初の呼び出しが完了するまで 2 番目の Ajax 呼び出しを本当に待ちたい場合など。

 function getData(m) {

    return $.ajax({
        url : myURL[m],  //<<<---Want to loop through this array
        type : 'GET',
        dataType: 'json',
        myJ: m
    });

    }


 function handleData(data){

    for (var i=0; i<data.test.msgOne.length; i++){
        myData[i] = data.test.msgOne[i];
    }

    for (var k=0; k<3; k++){
            document.write(myData[k])
            document.write('<br><br>');
    }
    if(this.myJ<2){
    var myJ=this.myJ;
       setTimeout(function(){
           getData((myJ+1)).done(handleData).fail(failed);
           }, 100);
    }
};



 getData(0).done(handleData);

function failed(jqXHR, textStatus, errorThrown){
 alert("textStatus="+textStatus);
alert("Error= "+errorThrown);
}

アラート付きのコメントに従って、動作している場合は settimeout.. を使用すると動作します

于 2013-05-16T17:17:08.053 に答える
0

常に 3 つの呼び出しがあることがわかっている場合は、次のようにすることができます。

function getData(url) {
    return $.ajax({
        url: url,
        //...
    });
}

function handleData(data1, data2, data3) {
    //display the data however you like
}

$(document).ready(function() { 

    var request1 = getData(myUrl[0]);
    var request2 = getData(myUrl[1]);
    var request3 = getData(myUrl[2]);

    $.when(request1, request2, request3)
        .done(function(result1, result2, result3) {
            alert(result1.test.msgOne[0]);
        });    

});

この場合、handleData()は 3 回の呼び出しがすべて終了した後に 1 回だけ呼び出されます。

結果の数がわからない場合は、myUrl 配列を反復処理して、deferreds を配列にプッシュできます。オブジェクトの配列を に渡す例については、このリンクを試してください。deferred$.when()

別の編集

元のコードを更新しました。遅延オブジェクトに夢中になっていると思います。遅延オブジェクト (request1など) には応答が含まれていません。jsonを呼び出すと$.when(request1).done(function(result1) { });、request1 の結果が関数に渡されます。

于 2013-05-17T14:51:23.823 に答える