2012-11-19 20 views
25

मैं थोड़ी देर के लिए इसके साथ संघर्ष कर रहा हूं। मैं जावास्क्रिप्ट के लिए नया हूं, और इस धारणा के तहत रहा हूं कि जिस कोड को मैं लिख रहा हूं वह असीमित रूप से चल रहा है। यहां एक सामान्य उदाहरण दिया गया है:जावास्क्रिप्ट वापसी मूल्यों के लिए प्रतीक्षा नहीं कर रहा है

मैं फ़ंक्शन ए में कुछ कोड चलाता हूं। फ़ंक्शन ए फिर फंक्शन बी को कॉल करता है, जिसे ए को एक वैरिएबल वापस करने की आवश्यकता होती है, ए इसे बाद के परिचालनों में उपयोग कर सकता है। ऐसा लगता है कि जब ए कॉल बी करता है, तब भी यह अपने कोड को जारी रखता है, इसके वापसी मूल्य के लिए अवरुद्ध इंतजार नहीं कर रहा है, और बी पर्याप्त तेज़ नहीं है कि एक बिंदु उस बिंदु तक पहुंच जाता है जहां उसे वापसी का उपयोग करने की आवश्यकता होती है मान और मुझे अपरिभाषित चर प्रकार त्रुटि मिलती है।

जिस तरह से मैंने इस बारे में काम किया है, उसके पास एक फंक्शन सी है जिसमें फिर एक फंक्शन सी कहा जाता है जो बाद के ऑपरेशन करेगा जो ए रिटर्न वैल्यू के साथ कर रहा होगा .... मैं तरह का क्रमबद्ध हूं रिटर्न के बजाय कॉल के माध्यम से अपने कोड ... कि बोझिल हालांकि है ...

यहाँ जब यह वास्तविक कोड में क्या होता है का एक उदाहरण है:

function initialize() { 
    //Geocode Address to obtin Lat and Long coordinates for the starting point of our map 
    geocoder = new google.maps.Geocoder(); 
    var results = geocode(geocoder); 
    makeMap(results[0].geometry.location.lat(), results[0].geometry.location.lng()); 

} 

function geocode(geocoder) { 
    //do geocoding here... 

    var address = "3630 University Street, Montreal, QC, Canada"; 
    geocoder.geocode({ 'address': address }, function (results, status) { 
     if (status == google.maps.GeocoderStatus.OK) { 
      return results; 
      } 
     else { 
      alert("Geocode was not successful for the following reason: " + status); 
     } 
    }); 

} 

function makeMap(lat, long) { 
    // alert(lat); for debuging 
    var mapOptions = { 
     center: new google.maps.LatLng(lat, long), 
     zoom: 17, 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 
    map = new google.maps.Map(document.getElementById("map_canvas"), 
     mapOptions); 
} 

नोट: इनिशियलाइज़ शरीर ऑनलोड से बुलाया जाता है = "मेरे एचटीएमएल में प्रारंभ करें()"।

तो मुद्दा यह है कि मेकमैप को जियोकोड फ़ंक्शन द्वारा प्राप्त अक्षांश और देशांतर मानों की आवश्यकता होती है, लेकिन मुझे कंसोल में एक त्रुटि मिलती है कि परिणाम अपरिभाषित हैं। क्या हो रहा है? मैं जावा से आया था इसलिए मैं जेएस में डेटा प्रवाह कैसे हो रहा है, इस बारे में थोड़ा उलझन में हूं! भविष्य के लिए यह मूल्यवान सबक होगा!

एक तरफ प्रश्न: मुझे बाहरी कार्यों में अपने कार्यों को कैसे विभाजित करना चाहिए? अच्छा अभ्यास क्या माना जाता है? क्या मेरे सभी कार्यों को एक बाहरी .js फ़ाइल में क्रैम किया जाना चाहिए या क्या मुझे एक साथ कार्यों की तरह समूह करना चाहिए?

+3

ठीक है, धन्यवाद, मैं यहां नया हूं! –

उत्तर

31

आप समस्या की अच्छी समझ है लगता है, लेकिन यह लगता है जैसे आप इसे हल करने के तरीके से परिचित नहीं हैं। इसका समाधान करने का सबसे आम तरीका कॉलबैक का उपयोग करना है। यह मूल रूप से वापसी मूल्य की प्रतीक्षा करने के लिए async तरीका है। यहां बताया गया है कि आप इसे अपने मामले में कैसे उपयोग कर सकते हैं:

function initialize() { 
    //Geocode Address to obtin Lat and Long coordinates for the starting point of our map 
    geocoder = new google.maps.Geocoder(); 
    geocode(geocoder, function(results) { 
     // This function gets called by the geocode function on success 
     makeMap(results[0].geometry.location.lat(), results[0].geometry.location.lng());   
    }); 
} 

function geocode(geocoder, callback) { 
    //do geocoding here... 

    var address = "3630 University Street, Montreal, QC, Canada"; 
    geocoder.geocode({ 'address': address }, function (results, status) { 
     if (status == google.maps.GeocoderStatus.OK) { 
      // Call the callback function instead of returning 
      callback(results); 
     } else { 
      alert("Geocode was not successful for the following reason: " + status); 
     } 
    }); 

} 

... 
11

मैं ... इस धारणा के तहत रहा हूं कि जो कोड मैं लिख रहा हूं वह असीमित रूप से चल रहा है।

हाँ, ऐसा करता है। आपका geocode फ़ंक्शन कॉल का परिणाम Google API पर वापस नहीं कर सकता है, क्योंकि Google कॉल पूरा होने से पहले फ़ंक्शन वापस आता है। नीचे नोट देखें: इतना है कि यह एक कॉलबैक जब यह परिणाम है जो यह कहते हैं स्वीकार करता

function geocode(geocoder) { 
    //do geocoding here... 

    var address = "3630 University Street, Montreal, QC, Canada"; 
    geocoder.geocode({ 'address': address }, function (results, status) { 
     if (status == google.maps.GeocoderStatus.OK) { 
      // +---------- This doesn't return anything from your 
      // v   geocode function, it returns a value from the callback 
      return results; 
      } 
     else { 
      alert("Geocode was not successful for the following reason: " + status); 
     } 
    }); 
} 

बजाय, आप अपनी geocode समारोह कोड होना चाहिए। उदा .:

// Added a callback arg ---v 
function geocode(geocoder, callback) { 
    //do geocoding here... 

    var address = "3630 University Street, Montreal, QC, Canada"; 
    geocoder.geocode({ 'address': address }, function (results, status) { 
     if (status == google.maps.GeocoderStatus.OK) { 
      // v---------- Call the callback 
      callback(results); 
      } 
     else { 
      alert("Geocode was not successful for the following reason: " + status); 
      callback(null); // <--- Call the callback with a flag value 
          // saying there was an error 
     } 
    }); 
} 

फिर, बजाय इस तरह प्रयोग करने के:

var results = geocode(someArgHere); 
if (results) { 
    doSomething(results); 
} 
else { 
    doSomethingElse(); 
} 

आप इसे इस तरह कहते हैं:

geocode(someArgHere, function() { 
    if (results) { 
     doSomething(results); 
    } 
    else { 
     doSomethingElse(); 
    } 
}); 

जैसे, तुम जाओ पूरी तरह से अतुल्यकालिक।

+0

यह नहीं है कि अनाम कार्य (जो दो पैरामीटर परिणाम, स्थिति लेता है) कर रहा है? –

+0

@GeorgesKrinker: हाँ, अगर आप कॉलिंग कोड पर लौटने से पहले परिणाम को बदलने की आवश्यकता नहीं है तो आप सीधे 'कॉलबैक' को Google पर पास कर सकते हैं। –

1

अज्ञात फ़ंक्शन के अंदर रिटर्न स्टेटमेंट अज्ञात फ़ंक्शन से लौटाता है, न कि बाहरी जियोकोड फ़ंक्शन से। Geocode समारोह अपरिभाषित लौटता है। Geocoder.geocode विधि जब भी चाहें, सिंक या async अनाम कार्य को कॉल कर सकते हैं। इसके लिए दस्तावेज़ों की जांच करें।

1

दरअसल, आप यह महसूस करने में सही हैं कि कॉल असीमित हैं, और आपको उचित वापसी मूल्य नहीं मिल रहा है।

आम तौर पर, जब जेएस में कार्यों को बुलाया जाता है, तो वे तुल्यकालिक होते हैं।

e.g. a() calls b(), and a() waits until b() to finish before continuing. 

हालांकि, इस तरह ajax या jsonp कॉल करने के रूप में कुछ स्थितियों में, यह अतुल्यकालिक रूप से किया जाता है। यह ठीक है जब आप geocode() पर कॉल करते हैं।

आपका निष्पादन:

initialize() is called; 
initialize() calls geocoder(); 
geocoder makes a request to Google, and returns null in the meantime. 
initialze() calls makemap() 
the Google geocoder returns at some point, and executed the success callback, which you have defined as "return results;", but there is nothing to return, since the function has already ended. 

तो, विशेष रूप से, कॉलबैक कि पहले से ही जियोकोडर कॉल में बनाया गया है का उपयोग:

if (status == google.maps.GeocoderStatus.OK) { 
    makeMap(results); 
} 
+0

ऐसा लगता है कि अगर बाहरी सेवा (जैसे एसिंक Google कॉल ऊपर) की कॉल के बजाय, मैं एक सरणी के माध्यम से looped और सरणी लौटा क्योंकि मुझे इसकी जरूरत है ... वह क्यों है? –

+0

यह तुल्यकालिक होना चाहिए। क्या आप इसे [jsFiddle] (http://jsfiddle.net) में पुन: उत्पन्न कर सकते हैं? –

+0

ठीक है मुझे यकीन नहीं है कि इसका उपयोग कैसे करें, लेकिन http://jsfiddle.net/gpLYH/1/ वह स्थान जहां समस्या होती है वह तब होती है जब loadData() कॉलस्टेशन() से डेटा को पुनः प्राप्त करने का प्रयास करने के बाद addMarkers() को कॉल करता है स्टेशनों के साथ एक सरणी वापस कर दिया जाना चाहिए था ... –

संबंधित मुद्दे