2014-09-29 19 views
11

我需要從Javascript/jQuery中的函數返回數組,但函數在設置數組之前返回(因爲它是AJAX調用)。添加對Google Maps API調用的承諾

我已被建議使用承諾,但我以前沒有使用過,迄今爲止無法將其實現到我的代碼中。這是我的代碼:

mapClass.setLatLng = function(location, clubs) {   
     document.geoCodeRequestCompleteFlag = 0; 
     geocoder = new google.maps.Geocoder();  
     geocoder.geocode({'address' : location}, function(results, status) {  
      //console.log(results); 
      if(status === "OK") {     
       var latLngArray = []; 
       latLngArray.push(parseFloat(results[0].geometry.location.lat())); 
       latLngArray.push(parseFloat(results[0].geometry.location.lng())); 
       var sortedArray = mapClass.calculateDistances(clubs, latLngArray); 
       return sortedArray; 
      }   
     });    
    } 

正如你所看到的,當我返回時,sortedArray變量是空的。有沒有人有任何想法,我可以添加阻止代碼,以確保在返回之前設置數組變量? 謝謝

回答

15

您使用承諾的方式是您創建一個承諾,然後從您的方法返回承諾。這個承諾有像.then(successHandler, errorHandler)這樣的方法,使您能夠指定在承諾解決(給定值)時執行的函數。然後,您在未來的某個時間從地理編碼器調用返回結果時解決承諾。

在jQuery中,承諾被稱爲Deferreds。然後

您的代碼將改變這樣的事情:

mapClass.setLatLng = function(location, clubs) { 
     var deferred = $.Deferred(), 
      geocoder = new google.maps.Geocoder(); 

     document.geoCodeRequestCompleteFlag = 0; 
     geocoder.geocode({'address' : location}, function(results, status) {  

     if (status === 'OK') {     
      var latLngArray = [ 
       +results[0].geometry.location.lat(), 
       +results[0].geometry.location.lng() 
      ]; 

      deferred.resolve(mapClass.calculateDistances(clubs, latLngArray)); 
     } else { 
      deferred.reject(status); 
     }   
    });    

    return deferred.promise(); 
} 

你會使用它,像這樣:如果你使用的是官方Google Maps Official NPM module

mapClass.setLatLng('123 Some St, Wherever', [/* clubs */]) 
.then(function (sortedArray) { 
    console.log('Promise resolved with: ', sortedArray); 
}, function (err) { 
    console.error('Uh oh! An error occurred!', err); 
}); 
+0

夢幻般的回答和解釋。謝謝。 – devoncrazylegs 2014-09-29 09:20:40

12

,你可以這樣做更容易和清潔器。

首先,你需要有一個Promise屬性初始化客戶端:

const googleMapsClient = require('@google/maps').createClient({ 
    key: 'your API key here', 
    Promise: Promise 
}); 

然後,所有你需要做的是使用asPromised()之後,你是好去:

googleMapsClient.geocode({ 
    address: '1600 Amphitheatre Parkway, Mountain View, CA' 
}) 
.asPromise() 
.then(response => response.json.results) 
.catch(err => console.log(err)) 
+0

有沒有模塊支持promise的任何文檔?我正在嘗試自己做這件事,但它不返回響應 – Stormie 2017-03-17 15:17:20

+0

但要小心 - 此NPM模塊用於服務器端API請求,並且只能與*服務器密鑰*一起使用。它不適用於XHR請求。 – 2017-03-17 16:06:18