2014-09-29 14 views
11

Ich muss ein Array von einer Funktion in Javascript/jQuery zurückgeben, aber die Funktion wird zurückgegeben, bevor das Array festgelegt wurde (wie es ein AJAX-Aufruf ist).Hinzufügen eines Versprechens zu einem Google Maps-API-Aufruf

Mir wurde geraten, ein Versprechen zu verwenden, aber ich habe diese zuvor noch nicht verwendet und konnte dies bisher nicht in meinen Code implementieren. Hier ist mein Code:

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

Wie Sie sehen können, die sortedArray Variable ist leer, wenn ich zurückkehre ist. Hat jemand irgendwelche Ideen, wie ich Blockierungscode hinzufügen könnte, um sicherzustellen, dass die Array-Variablen vor der Rückgabe gesetzt werden? Dank

Antwort

15

Die Art, wie Sie Versprechen verwenden, besteht darin, dass Sie ein Versprechen erstellen und dieses Versprechen dann von Ihrer Methode zurückgeben. Dieses Versprechen enthält Methoden wie .then(successHandler, errorHandler), mit denen Sie Funktionen angeben können, die ausgeführt werden sollen, wenn das Versprechen aufgelöst ist (wird ein Wert angegeben). Sie lösen dann das Versprechen, wenn Sie zu einem späteren Zeitpunkt die Ergebnisse des Geocodierer-Aufrufs abrufen.

In jQuery heißen die Versprechen Deferreds.

Ihr Code würde dann etwa wie folgt ändern:

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

Sie würden es wie so verwenden:

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

Fantastische Antwort und Erklärung. Vielen Dank. – devoncrazylegs

12

Wenn Sie die offizielle Google Maps Official NPM module verwenden, Sie können es viel einfacher und Reiniger.

Zuerst müssen Sie den Client mit einer Promise Eigenschaft initialisieren:

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

Dann alles, was Sie tun müssen, ist asPromised() verwenden und nach, dass Sie sind gut zu gehen:

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

Gibt es Unterlagen zur Modulunterstützung von Versprechungen? Ich versuche, dies selbst zu tun und es gibt keine Antwort – Stormie

+0

Seien Sie vorsichtig, dieses NPM-Modul ist für serverseitige API-Anfragen gedacht und funktioniert nur mit einem * Server-Schlüssel *. Es ist nicht für XHR-Anfragen gedacht. –

Verwandte Themen