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 我得到 undefined ... 当我做 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

As explained by a lot of answers, the problem is that you're trying to return something from the AJAX call back to the function which initiated the call. This cannot work, since the caller does not wait for the AJAX call to complete and will return before it is completed. That's the whole idea about asynchronous calls: you don't want to block the execution to wait for the results to come in.

One way to handle this is by passing a callback function which needs to be executed when the results are retrieved. This function will then be called from within the AJAX success callback.

Another interesting approach is to make use of jQuery's deferreds and promises. A promise represents some value which will be retrieved somewhere in the future. A deferred produces a promise and resolves it later on. For example, all AJAX functions return a promise and you can retrieve a promise from any jQuery object which is resolved when all animations are completed.

In your case, you can create a deferred which is resolved with the htmlContent when the AJAX results are retrieved. You return the promise of that deferred from the function so the caller can bind callbacks to it or combine it with other promises.

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

BEGIN EDIT

Thanks to Benjamin Gruenbaum for pointing out my usage of the deferred anti-pattern. Here's an implementation using .then to do the chaining:

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

END EDIT

You can then use the promise in your loadGraphs AJAX success callback like so:

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

The advantage of using promises is that they give caller much more flexibility. The caller can easily register multiple callbacks using then(), combine it with other promises using jQuery.when() or pipe the results to another promise using pipe() then.

于 2013-01-20T15:07:57.620 回答
0

是的。没有错误。您需要为您的函数定义不在 $.ajax 中的返回值。在您的代码中,您将值返回给 $.ajax,而不是 updateOverlijdens。正确的代码需要是:

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