如果为包含类.event
的每个div更改了值,我将使用下面的代码检索给定位置的纬度和经度。
我遇到的问题是此代码只发生了两个结果:
lat
和lon
变量lat
和lon
保持完全相同,就好像它们保持不变,因此不会替换JSON值。以下是我正在使用的代码:
$(".button").click(function(){
data = "";
$(".event").each(function(){
original = $(this).find(".address").data("original");
location = $(this).find(".address").html();
lat = $(this).find(".lat").html();
lon = $(this).find(".lon").html();
if (original !== location) {
$.getJSON( "http://nominatim.openstreetmap.org/search?q="+location+"&format=json&polygon=1&addressdetails=1", function(result) {
lat = result[0].lat;
lon = result[0].lon;
});
}
data = data + randomNumber() + ": " + lat + " " + lon + ",";
});
$(".data").val(data);
$(".form").submit();
});
变量data
将包含lat
和lon
,用于包含类event
的每个div。除非用户更改了地址,否则这些值将保持不变,此时将通过JSON请求再次检索它们。
然后应提交表格。
我该如何解决这个问题?谢谢
答案 0 :(得分:2)
$.getJSON
是异步的,你不能在回调函数之外引用结果。并且您不希望在所有 AJAX请求完成之前提交表单。
$.getJSON()
返回Deferred
。您可以创建所有这些数组,并使用$.when()
等待它们。
$(".button").click(function() {
var promises = [];
var data = "";
$(".event").each(function() {
var original = $(this).find(".address").data("original");
var location = $(this).find(".address").html();
var lat = $(this).find(".lat").html();
var lon = $(this).find(".lon").html();
if (original !== location) {
promises.push($.getJSON("http://nominatim.openstreetmap.org/search?q=" + location + "&format=json&polygon=1&addressdetails=1", function(result) {
var lat = result[0].lat;
var lon = result[0].lon;
data += randomNumber() + ": " + lat + " " + lon + ",";
}));
} else {
data += randomNumber() + ": " + lat + " " + lon + ",";
}
});
$.when.apply($, promises).done(function() {
$(".data").val(data);
$(".form").submit();
});
});
请注意data
中值的顺序是不可预测的,因为AJAX请求不一定按照它们发送的顺序返回。
您还应养成使用var
(或ES6中的let
)将变量声明为本地变量的习惯。
答案 1 :(得分:1)
我认为你应该同时调用$.getJSON
,然后在得到所有结果的同时处理所有结果。
如果某个位置不需要$.getJSON
,您可以创建立即解决延迟/承诺来模拟异步调用。这样我们就可以处理相同类型的结果(jQuery Promise Object)。
这是代码(不是测试)和评论:
$(".button").click(function() {
// data = "";
// unnecessary
// $(".event").each(function() {
// use map to get promise objects for every ".event"
var promises = $(".event").map(function() {
original = $(this).find(".address").data("original");
location = $(this).find(".address").html();
// lat = $(this).find(".lat").html();
// lon = $(this).find(".lon").html();
// not need here
if (original !== location) {
return $.getJSON("http://nominatim.openstreetmap.org/search?q=" + location + "&format=json&polygon=1&addressdetails=1", function(result) {
lat = result[0].lat;
lon = result[0].lon;
});
} else {
// make value type same as json, it's a array of { lat, lon }
return $.Deferred().resolve([{
lat: $(this).find(".lat").html(),
lon: $(this).find(".lon").html()
}]).promise();
}
// data = data + randomNumber() + ": " + lat + " " + lon + ",";
// do it later, after all promise resolved.
});
$.when.apply(null, promises)
.done(function() {
// convert arguments to a array
var args = [].slice.apply(arguments);
data = args
.map(function(models) {
// convert each model to a string
var model = models[0];
return randomNumber() + ": " + model.lat + " " + lon;
})
// join each part with separator ','
.join(",");
// while got data, deal with it
$(".data").val(data);
$(".form").submit();
});
});