1

これは私が持っているものです:

function loadGraphs(datawijk){

    $.ajax({                                      
      url: './api5.php',                  //the script to call to get data          
      data: {
       wijk: datawijk,
        },                        //you can insert url argumnets here to pass to api.php
                                       //for example "id=5&parent=6"
      dataType: 'json',                //data format      
      success: function(rows)          //on recieve of reply
      {
        var htmlContent = "";
        // ADD TO 

        htmlContent += '<tr><th scope="row">Geboortes</th>';

        $.each(rows, function(i, data) {
          $.each(data, function(j, year) {
            htmlContent += 
              '<td>' + year + '</td>';
          });
        });

        htmlContent += '</tr>';

        var lol = updateOverlijdens(datawijk, htmlContent);
        alert(lol);

        $('#graphs table tbody').html(htmlContent);
      }   
    });
}

function updateOverlijdens(datawijk, htmlContent){

    $.ajax({                                      
      url: './api4.php',                  //the script to call to get data          
      data: {
       wijk: datawijk,
        },                        //you can insert url argumnets here to pass to api.php
                                       //for example "id=5&parent=6"
      dataType: 'json',                //data format      
      success: function(rows)          //on recieve of reply
      {
        // ADD TO 

        htmlContent += '<tr><th scope="row">Overlijdens</th>';

        $.each(rows, function(i, data) {
          $.each(data, function(j, year) {
            htmlContent += 
              '<td>' + year + '</td>';
          });
        });

        htmlContent += '</tr>';

        return htmlContent;
      }   
    });
}

アラートをするとき(笑); 関数loadGraphsで未定義になります...そしてalert(htmlContent);を実行すると 関数updateOverlijdensで、値を返す直前に正しく取得します。関数loadGraphsの値を警告した場合にのみ、未定義になります。どうすればこれを修正できますか?

4

3 に答える 3

4

updateOverlijdens未定義になる理由は、 (成功した内部関数からではなく)何も返さないためです。

非同期コードを実行しています。通常、現在使用している関数の戻りパターンを使用してこの問題を簡単に解決することはできません。これは、戻り時にデータが利用できないためです。必要なのはコールバックです。

jQuery ajaxの適切な使用例については、このページを参照してください。やりたいことは、updateOverlijdensに関数を渡し、ajaxの成功コールバックが発生したときにそれを呼び出すことです。そのオンライン(および上記のリンク)の例はたくさんあります。

たとえば、非同期実行で発生した問題に対処する正しいコールバックパターンに変更された後のコードを次に示します。

function loadGraphs(datawijk){

    $.ajax({                                      
      url: './api5.php',                  //the script to call to get data          
      data: {
       wijk: datawijk,
        },                        //you can insert url argumnets here to pass to api.php
                                       //for example "id=5&parent=6"
      dataType: 'json',                //data format      
      success: function(rows)          //on recieve of reply
      {
        var htmlContent = "";
        // ADD TO 

        htmlContent += '<tr><th scope="row">Geboortes</th>';

        $.each(rows, function(i, data) {
          $.each(data, function(j, year) {
            htmlContent += 
              '<td>' + year + '</td>';
          });
        });

        htmlContent += '</tr>';
        updateOverlijdens(datawijk, htmlContent,function(lol){
            alert(lol);
            $('#graphs table tbody').html(lol);
        });

      }   
    });
}

function updateOverlijdens(datawijk, htmlContent,callback){

    $.ajax({                                      
      url: './api4.php',                  //the script to call to get data          
      data: {
       wijk: datawijk,
        },                        //you can insert url argumnets here to pass to api.php
                                       //for example "id=5&parent=6"
      dataType: 'json',                //data format      
      success: function(rows)          //on recieve of reply
      {
        // ADD TO 

        htmlContent += '<tr><th scope="row">Overlijdens</th>';

        $.each(rows, function(i, data) {
          $.each(data, function(j, year) {
            htmlContent += 
              '<td>' + year + '</td>';
          });
        });

        htmlContent += '</tr>';

        callback(htmlContent)
      }   
    });
}
于 2013-01-20T14:43:50.473 に答える
1

多くの回答で説明されているように、問題は、AJAX呼び出しから呼び出しを開始した関数に何かを戻そうとしていることです。呼び出し元はAJAX呼び出しが完了するのを待たず、完了する前に戻るため、これは機能しません。これが非同期呼び出しの全体像です。結果が届くのを待つために実行をブロックしたくないのです。

これを処理する1つの方法は、結果を取得するときに実行する必要があるコールバック関数を渡すことです。この関数は、AJAX成功コールバック内から呼び出されます。

もう1つの興味深いアプローチは、jQueryの据え置きpromiseを利用することです。promiseは、将来どこかで取得される値を表します。延期は約束を作成し、後でそれを解決します。たとえば、すべてのAJAX関数はpromiseを返し、すべてのアニメーションが完了したときに解決される任意のjQueryオブジェクトからpromiseを取得できます。

あなたの場合、htmlContentAJAX結果が取得されたときに解決される遅延を作成できます。関数から延期されたpromiseを返すので、呼び出し元はコールバックを関数にバインドしたり、他のpromiseと組み合わせたりできます。

function updateOverlijdens(datawijk) {
    // Create the deferred
    var dfd = new jQuery.Deferred();
    // Initiate the AJAX request
    $.ajax({                                      
        url: './api4.php',
        data: {
            wijk: datawijk,
        },
        dataType: 'json',
        success: function(rows) {
            var htmlContent = '<tr><th scope="row">Overlijdens</th>';

            $.each(rows, function(i, data) {
                $.each(data, function(j, year) {
                    htmlContent += '<td>' + year + '</td>';
                });
            });

            htmlContent += '</tr>';

            // Resolve the deferred
            dfd.resolve(htmlContent);
        },
        error: function() {
            // An error occurred, reject the deferred
            dfd.reject();
        }
    });
    // Return a promise
    return dfd.promise();
}

編集を開始

延期されたアンチパターンの使用法を指摘してくれたBenjaminGruenbaumに感謝します。.then連鎖を行うために使用する実装は次のとおりです。

function updateOverlijdens(datawijk) {
    return $.ajax({                                      
        url: './api4.php',
        data: {
            wijk: datawijk,
        },
        dataType: 'json'
    }).then(function(rows) {
        var htmlContent = '<tr><th scope="row">Overlijdens</th>';

        $.each(rows, function(i, data) {
            $.each(data, function(j, year) {
                htmlContent += '<td>' + year + '</td>';
            });
        });

        htmlContent += '</tr>';

        return htmlContent;
    });
}

編集終了

loadGraphs次に、次のようにAJAX成功コールバックでpromiseを使用できます。

// Produce the table header
var htmlContent = '<tr><th scope="row">Geboortes</th>';
$.each(rows, function(i, data) {
    $.each(data, function(j, year) {
        htmlContent += '<td>' + year + '</td>';
    });
});

var promise = updateOverlijdens(datawijk);
promise.then(function(htmlOverlijdens) {
    // Append to the previously created HTML content
    htmlContent += htmlOverlijdens;
    // Apply the HTML
    $('#graphs table tbody').html(htmlContent);
});

promiseを使用する利点は、発信者にはるかに柔軟性を与えることです。呼び出し元は、を使用して複数のコールバックを簡単に登録したり、を使用して他のPromisethen()と組み合わせたり、を使用しjQuery.when()て結果を別のPromiseにパイプしたりできます。pipe() then

于 2013-01-20T15:07:57.620 に答える
0

はい。間違いはありません。$.ajaxではなく関数の戻り値を定義する必要があります。コードでは、updateOverlijdensではなく$.ajaxに値を返します。正しいコードは次のとおりである必要があります。

function updateOverlijdens(datawijk, htmlContent){    
    $.ajax({ ....}) 
    return 'some value' 
}
于 2013-01-20T14:46:41.113 に答える