2014-09-29 3 views
11

Devo restituire un array da una funzione in Javascript/jQuery ma la funzione viene restituita prima che l'array sia stato impostato (poiché si tratta di una chiamata AJAX).Aggiunta di una promessa a una chiamata dell'API di Google Maps

Mi è stato consigliato di usare una promessa ma non li ho mai usati prima e finora non sono stato in grado di implementarlo nel mio codice. Qui è il mio codice:

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

Come si può vedere, la variabile SortedArray è vuoto quando torno è. Qualcuno ha qualche idea su come aggiungere codice di blocco in questo per garantire che le variabili dell'array siano impostate prima di tornare? Grazie

risposta

15

Il modo in cui usi le promesse è che tu crei una promessa e poi restituisci quella promessa dal tuo metodo. Questa promessa ha metodi come .then(successHandler, errorHandler) che consentono di specificare le funzioni da eseguire quando la promessa è risolta (viene assegnato un valore). Risolvi la promessa quando torni a ottenere i risultati dalla chiamata geocoder in futuro.

In jQuery, le promesse si chiamano Deferreds.

Il tuo codice sarebbe poi passare a qualcosa di simile:

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

Si potrebbe utilizzare in questo modo:

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

Risposta e spiegazione fantastiche. Grazie. – devoncrazylegs

12

Se si utilizza il funzionario Google Maps Official NPM module, Si può fare molto più facile e più pulito.

In primo luogo, è necessario inizializzare il cliente con una proprietà Promise:

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

Poi, tutto quello che dovete fare è usare asPromised() e dopo che si è pronti per partire:

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

c'è qualche documentazione per il supporto del modulo delle promesse? Sto cercando di farlo da solo e non restituisce una risposta – Stormie

+0

Attenzione però: questo modulo NPM è inteso per le richieste API lato server e funziona solo con una * chiave server *. Non è inteso per le richieste XHR. –

Problemi correlati