Javascript函数未定义

时间:2013-01-20 14:41:46

标签: php javascript jquery function

这就是我所拥有的:

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我得到未定义... 当我做警报时(htmlContent);在函数updateOverlijdens中,在我返回值之前,我就把它弄好了。只有当我提醒我的函数loadGraphs中的值时,我才会被定义。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

您未定义的原因是您没有从updateOverlijdens返回任何内容(但是从内部函数中成功返回)

您正在运行异步代码,通常使用当前正在使用的函数返回模式无法轻松解决此问题,因为返回时数据将不可用。你需要的是回调。

有关jQuery ajax的良好用法示例,请参阅this page。您要做的是将函数传递给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)
      }   
    });
}

答案 1 :(得分:1)

正如许多答案所解释的那样,问题在于您尝试将某些内容从AJAX调用返回到发起调用的函数。这不起作用,因为调用者不等待AJAX​​调用完成,并将在完成之前返回。关于异步调用的整个想法是:您不想阻止执行以等待结果进入。

处理此问题的一种方法是传递一个回调函数,该函数需要在检索结果时执行。然后将在AJAX成功回调中调用此函数。

另一个有趣的方法是使用jQuery的deferredpromise。承诺代表将来某处将被检索的某些价值。延迟产生一个承诺并在以后解决它。例如,所有AJAX函数都返回一个promise,您可以从任何jQuery对象中检索一个promise,该对象在完成所有动画后解析。

在您的情况下,您可以创建一个延迟,当检索到AJAX结果时,该延迟将使用htmlContent解析。您返回从函数延迟的承诺,以便调用者可以将回调绑定到它或将其与其他承诺结合起来。

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

开始编辑

感谢Benjamin Gruenbaum指出我对deferred anti-pattern的使用。这是使用.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成功回调中使用承诺,如下所示:

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

使用promises的优势在于它们为调用者提供了更大的灵活性。调用者可以使用then()轻松注册多个回调,使用jQuery.when()将其与其他承诺结合使用,或使用 pipe() then将结果传递给另一个承诺

答案 2 :(得分:0)

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

function updateOverlijdens(datawijk, htmlContent){    
    $.ajax({ ....}) 
    return 'some value' 
}