Javascript return 来自异步函数的值
Javascript return value from asynchronous function
我知道这是一个非常受欢迎且被多次回答的话题,但我
无法完全理解它在我的案例中的应用。
我正在通过 Javascript 学习我的方法,我一直在尝试 return 来自异步函数的值。本质上,我希望我的函数从 APIXU Weather API (https://www.apixu.com) 获取城市名称和 return 当前温度。
然后,我想在我的另一个 Google API 函数中使用这个函数。此函数获取点击标记的 ID,在地点数组中找到它的城市名称,并在信息窗口中显示信息,例如地点标题、城市天气和 Google 街景。我最初的计划是使用 populateInfoWindow 中的 getWeather 函数来查找城市的天气。有可能实现吗?因为据我了解,在同步内部使用异步函数会使最新的异步。我打算选择的另一种可能的方法是在文档加载时获取数组中所有位置的天气,然后在 populateInfoWindow 函数中从数组中获取信息。但恐怕这将是重复的和不必要的。
您认为完成它的最佳方法是什么以及如何避免类似问题?
代码如下:
//Get current forecast from weather API
function getWeather(city) {
var weatherAPIXU = "http://api.apixu.com/v1/current.json?key=XXXXXXXXXXXXXXX&q=" + city;
$.getJSON(weatherAPIXU, function(data) {
var forecast = data.current.temp_c;
var curWeather = forecast + '° C';
return curWeather
});
}
// Return a city name that matches a marker id
function getCityName(locations, marker) {
for (var i = 0, iLen = locations.length; i < iLen; i++) {
if (locations[i].id == marker.id) return locations[i].city;
}
}
// This function populates the infowindow when the marker is clicked. It'll only allow
// one infowindow which will open at the marker that is clicked, and populate based
// on that markers position.
function populateInfoWindow(marker, infowindow) {
// Check to make sure the infowindow is not already opened on this marker.
if (infowindow.marker != marker) {
// Clear the infowindow content to give the streetview time to load.
infowindow.setContent('');
infowindow.marker = marker;
// Make sure the marker property is cleared if the infowindow is closed.
infowindow.addListener('closeclick', function() {
infowindow.marker = null;
});
var streetViewService = new google.maps.StreetViewService();
var radius = 50;
var city = getCityName(locations, marker);
console.log(city);
var weatherInCity = getWeather(city);
console.log(weatherInCity);
// In case the status is OK, which means the pano was found, compute the
// position of the streetview image, then calculate the heading, then get a
// panorama from that and set the options
var getStreetView = function(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
var nearStreetViewLocation = data.location.latLng;
var heading = google.maps.geometry.spherical.computeHeading(
nearStreetViewLocation, marker.position);
infowindow.setContent('<div>' + marker.title + '' + weatherInCity +
'</div><div id="pano"></div>');
var panoramaOptions = {
position: nearStreetViewLocation,
pov: {
heading: heading,
pitch: 30
}
};
var panorama = new google.maps.StreetViewPanorama(
document.getElementById('pano'),
panoramaOptions);
} else {
infowindow.setContent('<div>' + marker.title +
'</div>' +
'<div>No Street View Found</div>');
}
};
// Use streetview service to get the closest streetview image within
// 50 meters of the markers position
streetViewService.getPanoramaByLocation(marker.position,
radius, getStreetView);
// Open the infowindow on the correct marker.
infowindow.open(map, marker);
}
}
您的函数可能 returns 一个值,我的猜测是您试图在函数 returns 之前使用该值。
你不能return这样的对象,因为它是回调函数。您可以在回调函数中编写逻辑。
function getWeather() {
var city = $("#txtCity").val();
var weatherAPIXU = "http://api.apixu.com/v1/current.json?key=XXXXXXX&q=" + city;
$.getJSON(weatherAPIXU, function(data) {
var forecast = data.current.temp_c;
var curWeather = forecast + '° C';
$("#lblTemp").html(curWeather)
});
另一个不推荐的选项是声明一个全局变量并将return值赋给全局变量。
var CurrentWeather = null
function getWeather(city) {
var weatherAPIXU = "http://api.apixu.com/v1/current.json?key=XXXXX&q=" + city;
$.getJSON(weatherAPIXU, function(data) {
var forecast = data.current.temp_c;
var curWeather = forecast + '° C';
$("#lblTemp").html(curWeather)
CurrentWeather = curWeather;
});
我知道这是一个非常受欢迎且被多次回答的话题,但我
无法完全理解它在我的案例中的应用。
我正在通过 Javascript 学习我的方法,我一直在尝试 return 来自异步函数的值。本质上,我希望我的函数从 APIXU Weather API (https://www.apixu.com) 获取城市名称和 return 当前温度。
然后,我想在我的另一个 Google API 函数中使用这个函数。此函数获取点击标记的 ID,在地点数组中找到它的城市名称,并在信息窗口中显示信息,例如地点标题、城市天气和 Google 街景。我最初的计划是使用 populateInfoWindow 中的 getWeather 函数来查找城市的天气。有可能实现吗?因为据我了解,在同步内部使用异步函数会使最新的异步。我打算选择的另一种可能的方法是在文档加载时获取数组中所有位置的天气,然后在 populateInfoWindow 函数中从数组中获取信息。但恐怕这将是重复的和不必要的。
您认为完成它的最佳方法是什么以及如何避免类似问题?
代码如下:
//Get current forecast from weather API
function getWeather(city) {
var weatherAPIXU = "http://api.apixu.com/v1/current.json?key=XXXXXXXXXXXXXXX&q=" + city;
$.getJSON(weatherAPIXU, function(data) {
var forecast = data.current.temp_c;
var curWeather = forecast + '° C';
return curWeather
});
}
// Return a city name that matches a marker id
function getCityName(locations, marker) {
for (var i = 0, iLen = locations.length; i < iLen; i++) {
if (locations[i].id == marker.id) return locations[i].city;
}
}
// This function populates the infowindow when the marker is clicked. It'll only allow
// one infowindow which will open at the marker that is clicked, and populate based
// on that markers position.
function populateInfoWindow(marker, infowindow) {
// Check to make sure the infowindow is not already opened on this marker.
if (infowindow.marker != marker) {
// Clear the infowindow content to give the streetview time to load.
infowindow.setContent('');
infowindow.marker = marker;
// Make sure the marker property is cleared if the infowindow is closed.
infowindow.addListener('closeclick', function() {
infowindow.marker = null;
});
var streetViewService = new google.maps.StreetViewService();
var radius = 50;
var city = getCityName(locations, marker);
console.log(city);
var weatherInCity = getWeather(city);
console.log(weatherInCity);
// In case the status is OK, which means the pano was found, compute the
// position of the streetview image, then calculate the heading, then get a
// panorama from that and set the options
var getStreetView = function(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
var nearStreetViewLocation = data.location.latLng;
var heading = google.maps.geometry.spherical.computeHeading(
nearStreetViewLocation, marker.position);
infowindow.setContent('<div>' + marker.title + '' + weatherInCity +
'</div><div id="pano"></div>');
var panoramaOptions = {
position: nearStreetViewLocation,
pov: {
heading: heading,
pitch: 30
}
};
var panorama = new google.maps.StreetViewPanorama(
document.getElementById('pano'),
panoramaOptions);
} else {
infowindow.setContent('<div>' + marker.title +
'</div>' +
'<div>No Street View Found</div>');
}
};
// Use streetview service to get the closest streetview image within
// 50 meters of the markers position
streetViewService.getPanoramaByLocation(marker.position,
radius, getStreetView);
// Open the infowindow on the correct marker.
infowindow.open(map, marker);
}
}
您的函数可能 returns 一个值,我的猜测是您试图在函数 returns 之前使用该值。
你不能return这样的对象,因为它是回调函数。您可以在回调函数中编写逻辑。
function getWeather() {
var city = $("#txtCity").val();
var weatherAPIXU = "http://api.apixu.com/v1/current.json?key=XXXXXXX&q=" + city;
$.getJSON(weatherAPIXU, function(data) {
var forecast = data.current.temp_c;
var curWeather = forecast + '° C';
$("#lblTemp").html(curWeather)
});
另一个不推荐的选项是声明一个全局变量并将return值赋给全局变量。
var CurrentWeather = null
function getWeather(city) {
var weatherAPIXU = "http://api.apixu.com/v1/current.json?key=XXXXX&q=" + city;
$.getJSON(weatherAPIXU, function(data) {
var forecast = data.current.temp_c;
var curWeather = forecast + '° C';
$("#lblTemp").html(curWeather)
CurrentWeather = curWeather;
});