我正在使用Node.js.我创建了一个名为locationToAddress的函数,但它始终返回undefined。这是简化的代码:
var lat = '-34.491093';
var long = '-58.558597';
console.log(locationToAddress(lat, long));
function locationToAddress(lat, long) {
var preUrl = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=';
var apiKey = '<API_KEY>';
var url = preUrl + lat + ',' + long + apiKey;
var addressString = '';
request(url, function (error, response, body) {
try {
var jsonLocationObject = JSON.parse(body);
addressString = JSON.stringify(jsonLocationObject.results[0].formatted_address);
addressString = addressString.replace(/["]/g, '');
console.log(addressString);
return addressString;
} catch (e) {
return 'Could not find address';
}
});
}
在控制台中,此代码应视为:
<FORMATTED_ADDRESS>
<FORMATTED_ADDRESS>
但我明白了:
undefined
<FORMATTED_ADDRESS>
我知道错误在于返回值,因为如果我在没有记录返回值的情况下调用函数,它将完美地工作。
答案 0 :(得分:0)
这是因为locationToAddress
没有返回任何内容。 return addressString;
和return 'Could not find address';
不是locationToAddress的“部分”。
因为locationToAddress
中的请求是异步的,我打赌你想使用具有不同签名的函数:
function locationToAddress(lat, long, callback) { // see the param 'callback'
然后在request(url, function (error, response, body) {
中,您将不会使用return
,而是使用callback(null, addressString)
和callback('Could not find address')
。 callback
中的第一个参数始终是错误的,简洁的是您想要返回的数据。
请注意,在NodeJS中,大多数代码都是异步的,您必须这样处理它。要使代码看起来同步,请查看async.js。我一直使用的功能是series
,waterfall
和autoInject
。
*使用回调完成重写*
function locationToAddress(lat, long, callback) { // <--- CHANGE
var preUrl = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=';
var apiKey = '<API_KEY>';
var url = preUrl + lat + ',' + long + apiKey;
var addressString = '';
request(url, function (error, response, body) {
try {
var jsonLocationObject = JSON.parse(body);
addressString = JSON.stringify(jsonLocationObject.results[0].formatted_address);
addressString = addressString.replace(/["]/g, '');
console.log(addressString);
return callback(null, addressString); // CHANGE - null represents "no error"
} catch (e) {
return callback('Could not find address'); // CHANGE - nonnull 1st param means an error occured
}
});
}