2017-06-19 76 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(); 
     }); 
});