Javascript Nested Function - Need help returning result
I am trying to create a function to return a lat/long array from the Google Maps JS API (v3). I am able to write the data out that I retrieve from the API, but I am not able to pass the data along to a variable. I am wanting to do something like this:
var latLong = getLatLong(Address);
The function that I have created is here:
function getLatLong(loc, callback) {
var geocoder = new google.maps.Geocoder();
var array = new Array();
if (geocoder) {
geocoder.geocode({ 'address': loc }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latLng = results[0].geometry.location;;
$.each(latLng, function(k, v) {
if (k == 'va' || k == 'wa') {
array.push(v);
}
});
var ret = array;
callback(ret);
} else {
console.log("Geocoding failed: " + status);
}
});
}
}
I then am assigning the function to a variable and calling it to give me the lat/long.
var geo = getLatLong('Dallas, TX', function(result) {
return result;
});
Unfortunately this produces an 'undefined' result. I can access the result in the function, I just can't pass it al开发者_运维技巧ong. How can I pass the result of the function to a variable to be accessed?
Unfortunately this produces an 'undefined' result
Do you mean in the 'geo' variable? If so, you are missing the point of callbacks. The function you pass in will be called later after the getLatLong() call returns. Callbacks are asynchronous functions, and you will want to use the callback to take an action (e.g. change state, tweak a display, etc.) of your choice.
Try changing it to
function(result) { alert('callback result: '+result); }
to check if it gets called properly. If you get an alert()
properly, then you might want to do something like this:
var geo = null;
getLatLong('Dallas, TX', function(result) {
// cache state
geo = result;
// do something with it
showResultInSomeSpotOnThePage(result);
});
/* We can't use the "geo" variable contents immediately
* after getLatLong returns; it will be set at some time later.
* But there may be some use for keeping the result around indefinitely,
* we just have to be prepared for "geo" to be null if we check it
* before the callback is called.
*/
You can't structure the code the way you want to here. The problem is that geocoder.geocode()
is an asynchronous operation. That's why it takes a callback function. When you call geocoder.geocode()
, it initiates the request to fetch the geocode, and then returns, leaving the request running in the background. When the request eventually completes, google's api will execute the anonymous function you passed as the second parameter to geocode()
.
So when you call getLatLong()
the actual order that things happen is something like this:
- call
geocoder.geocode()
. (initiates geocode request) getLatLong()
is done and returns undefined. (this is wheregeo
gets set)- (the geocode request completes) google api calls the anonymous function, which pushes the LatLng values into
array
, and then calls yourcallback()
to better visualize what's going on, you might write your code as follows (this is exactly equivalent to the way you've written it):
function getLatLong(loc, callback) {
var geocoder = new google.maps.Geocoder();
var array = new Array();
function handleGeocodeResponse(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latLng = results[0].geometry.location;;
$.each(latLng, function(k, v) {
if (k == 'va' || k == 'wa') {
array.push(v);
}
});
var ret = array;
callback(ret);
}
}
if (geocoder) {
geocoder.geocode({ 'address': loc }, handleGeocodeResponse);
} else {
console.log("Geocoding failed: " + status);
}
// note- no return specified explicitly is the same as
//return undefined;
}
So, if you can't return a value, then how do you use the results? Like this:
getLatLong('Dallas, TX', function(geo) {
// geo is passed to this function as a parameter
// move all code that requires `geo` into this function.
});
The key point here is that getLatLong
doesn't return a value. That is why geo
is always undefined.
To make this work, you'll need to modify your callback function. Something like this:
getLatLong('Dallas, TX', function(result)
{
var geo = result;
//continue to use geo here as you normally would
});
geo is undefined because getLatLong() doesn't return anything (which means it returns undefined).
精彩评论