wake-up-neo.com

Rückgabewert von verschachtelter Funktion in Javascript

Ich habe eine Funktion, die wie folgt eingerichtet ist

function mainFunction() {
      function subFunction() {
            var str = "foo";
            return str;
      }
}

var test = mainFunction();
alert(test);

Meiner Logik nach sollte diese Warnung 'foo' zurückgeben, aber stattdessen undefiniert. Was mache ich falsch?

UPDATE : Hier ist mein aktueller Code (eine Funktion zum Reverse-Geocodieren mit der Google-API)

function reverseGeocode(latitude,longitude){
    var address = "";
    var country = "";
    var countrycode = "";
    var locality = "";

    var geocoder = new GClientGeocoder();
    var latlng = new GLatLng(latitude, longitude);

     return geocoder.getLocations(latlng, function(addresses) {
     address = addresses.Placemark[0].address;
     country = addresses.Placemark[0].AddressDetails.Country.CountryName;
     countrycode = addresses.Placemark[0].AddressDetails.Country.CountryNameCode;
     locality = addresses.Placemark[0].AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
     return country;
    });   
   }
54
Chris Armstrong

sie müssen eine Funktion aufrufen, bevor sie etwas zurückgeben kann.

function mainFunction() {
      function subFunction() {
            var str = "foo";
            return str;
      }
      return subFunction();
}

var test = mainFunction();
alert(test);

Oder:

function mainFunction() {
      function subFunction() {
            var str = "foo";
            return str;
      }
      return subFunction;
}

var test = mainFunction();
alert( test() );

für Ihren tatsächlichen Code. Die Rückgabe sollte in der Hauptfunktion außerhalb erfolgen. Der Rückruf wird irgendwo in der getLocations -Methode aufgerufen und daher wird sein Rückgabewert nicht in Ihrer Hauptfunktion empfangen.

function reverseGeocode(latitude,longitude){
    var address = "";
    var country = "";
    var countrycode = "";
    var locality = "";

    var geocoder = new GClientGeocoder();
    var latlng = new GLatLng(latitude, longitude);

    geocoder.getLocations(latlng, function(addresses) {
     address = addresses.Placemark[0].address;
     country = addresses.Placemark[0].AddressDetails.Country.CountryName;
     countrycode = addresses.Placemark[0].AddressDetails.Country.CountryNameCode;
     locality = addresses.Placemark[0].AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
    });   
    return country
   }
60
z33m

Richtig. Die Funktion, die Sie an getLocations () übergeben, wird erst aufgerufen, wenn die Daten verfügbar sind. Wenn Sie also "country" zurückgeben, bevor sie festgelegt wurden, hilft dies nichts.

Dazu müssen Sie die Funktion, die Sie an geocoder.getLocations () übergeben, mit den zurückgegebenen Werten nach Belieben ausführen.

Etwas wie das:

function reverseGeocode(latitude,longitude){
  var geocoder = new GClientGeocoder();
  var latlng = new GLatLng(latitude, longitude);

  geocoder.getLocations(latlng, function(addresses) {
    var address = addresses.Placemark[0].address;
    var country = addresses.Placemark[0].AddressDetails.Country.CountryName;
    var countrycode = addresses.Placemark[0].AddressDetails.Country.CountryNameCode;
    var locality = addresses.Placemark[0].AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
    do_something_with_address(address, country, countrycode, locality);
  });   
}

function do_something_with_address(address, country, countrycode, locality) {
  if (country==="USA") {
     alert("USA A-OK!"); // or whatever
  }
}

Wenn Sie bei jedem Abrufen des Speicherorts etwas anderes tun möchten, übergeben Sie die Funktion als zusätzlichen Parameter an reverseGeocode:

function reverseGeocode(latitude,longitude, callback){
  // Function contents the same as above, then
  callback(address, country, countrycode, locality);
}
reverseGeocode(latitude, longitude, do_something_with_address);

Wenn dies ein wenig chaotisch aussieht, können Sie sich die Funktion "Zurückgestellt" in Dojo ansehen, mit der die Verkettung zwischen Funktionen etwas klarer wird.

3
Mark Bessey

Nur zu Ihrer Information, Geocoder ist asynchron, sodass die akzeptierte Antwort, während sie logisch ist, in dieser Instanz nicht wirklich funktioniert. Ich würde es vorziehen, ein externes Objekt zu haben, das als Updater fungiert.

var updater = {};

function geoCodeCity(goocoord) { 
    var geocoder = new google.maps.Geocoder();
    geocoder.geocode({
        'latLng': goocoord
    }, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            updater.currentLocation = results[1].formatted_address;
        } else {
            if (status == "ERROR") { 
                    console.log(status);
                }
        }
    });
};
1
efwjames