I've been struggling with this for a while now. I'm new to Javascript, and have been under the impression that the code I've been writing has been running asynchronously. Here is a generic example:
I run some code in function a. Function A then calls Function B, who needs to return a variable to A so A can use it in its later operations. It seems though that when A calls B, it still continues to run its own code, not waiting blocked for its return value, and B isn't fast enough such that A ends up reaching the point where it would have needed to use the return value and I get an undefined variable type error.
The way I have worked around this is have function A call Function B which then calls a Function C that would do what the later operations that A would be doing with the return value....I'm kind of serializing my code through calls instead of returns...that is cumbersome though...
Here is an example of when it happens in actual code:
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); }
Note: initialize gets called by body onload="initialize()" in my html.
So the issue is that the makeMap requires the lat and longitude values obtained by the Geocode function, but I get an error in the console saying results is undefined. What is going on? I came from Java so I'm a little confused about how data flow is happening here in JS! This will be valuable lessons for the future!
On a side question: How should I split my functions across external scripts? What is considered good practice? should all my functions be crammed into one external .js file or should I group like functions together?
You can use the async/await syntax or call the . then() method on a promise to wait for it to resolve. Inside of functions marked with the async keyword, you can use await to wait for the promises to resolve before continuing to the next line of the function.
JavaScript may not have a sleep() or wait() function, but it is easy enough to create one using the built-in setTimeout() function — as long as you are careful with how you use it.
You seem to have a good understanding of the problem, but it sounds like you aren't familiar with the way to solve it. The most common way to address this is by using a callback. This is basically the async way to wait for a return value. Here's how you could use it in your case:
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); } }); } ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With