我正在尝试以面向对象的方式使用 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/