2017-06-19 79 views
0

如果对于包含类.event的每个div更改了值,我正在使用以下代码检索给定位置的经度和纬度。JSON请求在jQuery中无法正常工作每个函数

时遇到的问题是,只有两个结果从该代码发生:

  • 的值从一个JSON请求返回被用于每latlon可变
  • 变量latlon保持完全一样,就好像它们保持不变,所以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将包含含有类event每个格的latlon。除非用户更改地址,否则这些值将保持不变,在此时他们将通过JSON请求再次被检索。

然后提交表格。

我该如何解决这个问题?谢谢

+0

'$ .getJSON'是异步的。你在回调函数执行前设置'data'。 – Barmar

回答

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)。

+0

非常感谢您的支持!因为它已经被声明为变量,所以还需要在JSON请求下面使用'var lat/lon'?代码有点儿有一些具有相同地址的事件,所以我不得不删除它。 – Osman

+1

除非实际需要,否则最好避免在不同功能之间共享变量。 AJAX回调函数不需要使用与迭代函数相同的'lat/lon'变量。 – Barmar

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