javascript - 从 jQuery Ajax 方法返回值

标签 javascript jquery ajax

我正在尝试以面向对象的方式使用 Javascript,并且一种方法需要进行远程调用来获取一些数据,以便网页可以使用它。我创建了一个 Javascript 类来封装数据检索,以便我可以在其他地方重用逻辑,如下所示:

 AddressRetriever = function() { 
   AddressRetriever.prototype.find = function(zip) { 
       var addressList = [];
       $.ajax({ 
           /* setup stuff */
           success: function(response) { 
               var data = $.parseJSON(response.value);
               for (var i = 0; i < data.length; i++) { 
                   var city = data[i].City; // "City" column of DataTable
                   var state = data[i].State; // "State" column of DataTable
                   var address = new PostalAddress(postalCode, city, state); // This is a custom JavaScript class with simple getters, a DTO basically.
                   addressList.push(address);
               }
           }
       });
       return addressList;
   }
 }

网页本身如下调用:

$('#txtZip').blur(function() { 
    var retriever = new AddressRetriever();
    var addresses = retriever.find($(this).val());

    if (addresses.length > 0) { 
        $('#txtCity').val(addresses[0].getCity());
        $('#txtState').val(addresses[0].getState());
    }
});

问题是有时地址莫名其妙地为空(即长度= 0)。在 Firebug 中,XHR 选项卡显示带有预期数据的响应,如果我在成功方法内部设置警报,则长度是正确的,但在该方法之外,当我尝试返回值时,有时(但并非总是如此) )为空,我的文本框未填充。有时它显示为空,但文本框无论如何都会正确填充。

我知道我可以通过摆脱单独的类并将整个 ajax 调用填充到事件处理程序中来做到这一点,但我正在寻找一种正确执行此操作的方法,以便在必要时可以重用该函数。有什么想法吗?

最佳答案

简而言之,您无法按照异步 ajax 调用的方式进行操作。

Ajax 方法通常异步运行。因此,当 ajax 函数调用本身返回时(您的代码中有 return addressList ),实际的 ajax 网络尚未完成,结果尚不清楚。

相反,您需要重新设计代码流程的工作方式,并仅在成功处理程序或从成功处理程序调用的函数中处理 ajax 调用的结果。只有当成功处理程序被调用时,ajax 网络才完成并提供结果。

简而言之,使用异步ajax调用时无法进行正常的过程式编程。您必须更改代码的结构和流程方式。它确实使事情变得复杂,但使用异步 ajax 调用的用户体验优势是巨大的(浏览器不会在网络操作期间锁定)。

以下是如何使用回调函数重构代码,同时仍然保持 AddressRetriever.find() 方法相当通用:

AddressRetriever = function() { 
   AddressRetriever.prototype.find = function(zip, callback) { 
       $.ajax({ 
           /* setup stuff */
           success: function(response) { 
               var addressList = [];
               var data = $.parseJSON(response.value);
               for (var i = 0; i < data.length; i++) { 
                   var city = data[i].City; // "City" column of DataTable
                   var state = data[i].State; // "State" column of DataTable
                   var address = new PostalAddress(postalCode, city, state); // This is a custom JavaScript class with simple getters, a DTO basically.
                   addressList.push(address);
               }
               callback(addressList);
           }
       });
   }
 }

$('#txtZip').blur(function() { 
    var retriever = new AddressRetriever();
    retriever.find($(this).val(), function(addresses) {
        if (addresses.length > 0) { 
            $('#txtCity').val(addresses[0].getCity());
            $('#txtState').val(addresses[0].getState());
        }
    });

});

关于javascript - 从 jQuery Ajax 方法返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8809466/

相关文章:

php - xajax替代品?

jquery - 删除 Ajax 在本地主机中有效,但在生产托管中无效

javascript - 查找父级是否为表

javascript - 模态窗口/foundation.reveal.js 并传递一个变量

javascript - Backbone Marionette - 布局 View 僵尸

javascript - 如何在数组值上添加单击事件并更改文本框值?

javascript - 为什么 <Route component={Menu}/> 而不是 <Menu/>?

php - 如何阻止 yii cgridview 在每个 ajax 更新调用中获取它的 jquery 文件

javascript - 使用 for 循环调用函数时浏览器崩溃

javascript - 形成键+值对jquery插件