2014-09-29 18 views
11

पर एक वादा जोड़ना मुझे जावास्क्रिप्ट/jQuery में किसी फ़ंक्शन से एक सरणी वापस करने की आवश्यकता है, लेकिन सरणी सेट होने से पहले फ़ंक्शन वापस आ रहा है (क्योंकि यह एक AJAX कॉल है)।Google मानचित्र 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) जैसी विधियां हैं जो आपको संकल्प (मान दिया जाता है) को निष्पादित करने के लिए कार्य निर्दिष्ट करने में सक्षम बनाता है। जब आप भविष्य में किसी बिंदु पर geocoder कॉल से परिणाम वापस प्राप्त करते हैं तो आप वादे को हल करते हैं।

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

आप यह इतना तरह का प्रयोग करेंगे:

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

12

आप आधिकारिक Google Maps Official NPM module का उपयोग कर रहे हैं, तो आप यह कर सकते बहुत आसान है और सफाई वाला।

पहले, आप एक 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

क्या वादे के मॉड्यूल समर्थन के लिए कोई दस्तावेज है? मैं इसे स्वयं करने की कोशिश कर रहा हूं और यह प्रतिक्रिया वापस नहीं करता है – Stormie

+0

हालांकि सावधान रहें - यह एनपीएम मॉड्यूल सर्वर-साइड एपीआई अनुरोधों के लिए है और केवल * सर्वर कुंजी * के साथ काम करता है। यह एक्सएचआर अनुरोधों के लिए नहीं है। –