我试图从Javascript中的异步函数返回结果。
我已经看到了这个问题:How do I return the response from an asynchronous call?,我正在尝试实现回调解决方案,但是出了点问题。
这是我的代码:
function getLocation(callback){
var lat;
var long;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position)
{
lat = position.coords.latitude;
long = position.coords.longitude;
}, function()
{
console.log('Please enable geolocation in your browser.');
});
} else {
alert('It seems like geolocation is not enabled in your browser.');
}
var res = {
"lat": lat,
"long": long
};
callback(res);
}
function getEventNearYou(){
var list = [];
getLocation(function(obj){
var lat = obj.lat;
var long = obj.long;
$.ajax({
url : 'http://www.skiddle.com/api/v1/events/search/?api_key=myapikey' + '&latitude=' + lat + '&longitude=' + long + '&radius=800&eventcode=LIVE&order=distance&description=1',
type : "GET",
async : false,
success : function(response) {
$(response).find("results").each(function() {
var el = $(this);
var obj = {
"eventname" : el.find("eventname").text(),
"imageurl" : el.find("imageurl").text(),
}
list.push(obj);
});
}
});
return list;
});
}
基本上,我想找到我当前的位置,并向www.skiddle.com创建一个HTTP get请求,以检索该位置附近的事件。
这就是我调用函数的方式:
var x = getEventNearYou();
但我似乎犯了一个错误,因为我收到了错误的请求错误(lat
和long
未定义)。
答案 0 :(得分:2)
您以一种破坏其有用性的方式使用回调。您仍然以同步方式编写代码。您应该继续参考:{{3}}
与此同时,我会重新构建您的代码,以显示它是如何完成的。
根据经验,如果函数中的任何代码使用回调,那么外部函数也需要接受回调作为参数。
如果在回调函数中为变量赋值,则不会在回调函数之外定义它(因为异步代码总是在同步代码之后运行)。 / p>
请勿使用async: false
function getLocation(callback){
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
var lat = position.coords.latitude;
var long = position.coords.longitude;
var res = { "lat": lat, "long": long };
callback(res);
}, function() {
console.log('Please enable geolocation in your browser.');
});
} else {
alert('It seems like geolocation is not enabled in your browser.');
}
}
function getEventNearYou(callback) {
getLocation(function(pos){
var lat = pos.lat;
var long = pos.long;
$.ajax({
url: 'http://www.skiddle.com/api/v1/events/search/?api_key=myapikey' + '&latitude=' + lat + '&longitude=' + long + '&radius=800&eventcode=LIVE&order=distance&description=1',
type: "GET",
success: function(response) {
var list = [];
$(response).find("results").each(function() {
var el = $(this);
var obj = {
"eventname": el.find("eventname").text(),
"imageurl" : el.find("imageurl").text(),
};
list.push(obj);
});
callback(list);
}
});
});
}
然后使用回调函数调用getEventNearYou
:
getEventNearYou(function (events) {
// code which relies on `events` can be called from here
});
答案 1 :(得分:0)
为4castle的优秀答案添加更多解释。在您编写的代码中,当您在Javascript中调用getLocation()
函数时,会发生这种情况:
var lat
和var long
的实例化值为undefined
。navigator.geolocation.getCurrentPosition()
被调用,需要很长时间才能完成。res
对象使用lat
和long
的当前未定义值进行实例化。也就是说,res
是:{ "lat": undefined, "long": undefined }
callback
上调用res
函数。这意味着调用了callback
lat
和long
的未定义值。navigator.geolocation.getCurrentPosition()
终于完成了它正在做的事情,并将值分配给lat
和long
,但到现在为时已晚,因为已经在未定义的值上调用了回调函数。 / LI>
醇>
在4castle的修订代码中,步骤4-5被放入navigator.geolocation.getCurrentPosition()
的匿名回调函数中,这意味着在getCurrentPosition()
完成获取位置之前不会执行这些行。