从Javascript中的嵌套函数返回值[重复]

时间:2022-04-17 15:55:47

This question already has an answer here:

这个问题在这里已有答案:

I have a function that is set up as follows

我有一个功能,设置如下

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

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

To my logic, that alert should return 'foo', but instead it returns undefined. What am I doing wrong?

根据我的逻辑,该警报应返回'foo',而是返回undefined。我究竟做错了什么?

UPDATE: Here's my actual code (it's a function for reverse-geocoding with the Google API)

更新:这是我的实际代码(它是使用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;
    });   
   }

3 个解决方案

#1


57  

you have to call a function before it can return anything.

你必须先调用一个函数才能返回任何东西。

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

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

Or:

要么:

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

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

for your actual code. The return should be outside, in the main function. The callback is called somewhere inside the getLocations method and hence its return value is not recieved inside your main function.

为您的实际代码。返回应该在主函数外部。回调是在getLocations方法内部的某处调用的,因此它的返回值不会在main函数中被收到。

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
   }

#2


3  

Right. The function you pass to getLocations() won't get called until the data is available, so returning "country" before it's been set isn't going to help you.

对。传递给getLocations()的函数在数据可用之前不会被调用,因此在设置之前返回“country”对你没有帮助。

The way you need to do this is to have the function that you pass to geocoder.getLocations() actually do whatever it is you wanted done with the returned values.

您需要这样做的方法是让您传递给geocoder.getLocations()的函数实际执行您想要使用返回值完成的任何操作。

Something like this:

像这样的东西:

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
  }
}

If you might want to do something different every time you get the location, then pass the function as an additional parameter to reverseGeocode:

如果您每次获得位置时可能想要做一些不同的事情,那么将该函数作为附加参数传递给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);

If this looks a little messy, then you could take a look at something like the Deferred feature in Dojo, which makes the chaining between functions a little clearer.

如果这看起来有点混乱,那么你可以看看Dojo中的Deferred功能,这使得函数之间的链接更加清晰。

#3


1  

Just FYI, Geocoder is asynchronous so the accepted answer while logical doesn't really work in this instance. I would prefer to have an outside object that acts as your updater.

仅供参考,Geocoder是异步的,所以接受的答案虽然逻辑在这个实例中并不真正起作用。我希望有一个外部对象充当你的更新程序。

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


57  

you have to call a function before it can return anything.

你必须先调用一个函数才能返回任何东西。

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

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

Or:

要么:

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

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

for your actual code. The return should be outside, in the main function. The callback is called somewhere inside the getLocations method and hence its return value is not recieved inside your main function.

为您的实际代码。返回应该在主函数外部。回调是在getLocations方法内部的某处调用的,因此它的返回值不会在main函数中被收到。

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
   }

#2


3  

Right. The function you pass to getLocations() won't get called until the data is available, so returning "country" before it's been set isn't going to help you.

对。传递给getLocations()的函数在数据可用之前不会被调用,因此在设置之前返回“country”对你没有帮助。

The way you need to do this is to have the function that you pass to geocoder.getLocations() actually do whatever it is you wanted done with the returned values.

您需要这样做的方法是让您传递给geocoder.getLocations()的函数实际执行您想要使用返回值完成的任何操作。

Something like this:

像这样的东西:

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
  }
}

If you might want to do something different every time you get the location, then pass the function as an additional parameter to reverseGeocode:

如果您每次获得位置时可能想要做一些不同的事情,那么将该函数作为附加参数传递给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);

If this looks a little messy, then you could take a look at something like the Deferred feature in Dojo, which makes the chaining between functions a little clearer.

如果这看起来有点混乱,那么你可以看看Dojo中的Deferred功能,这使得函数之间的链接更加清晰。

#3


1  

Just FYI, Geocoder is asynchronous so the accepted answer while logical doesn't really work in this instance. I would prefer to have an outside object that acts as your updater.

仅供参考,Geocoder是异步的,所以接受的答案虽然逻辑在这个实例中并不真正起作用。我希望有一个外部对象充当你的更新程序。

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