[英]Javascript asynchronous function: callback not working
I am trying to return a result from an asynchronous function in Javascript. 我正在尝试从Javascript中的异步函数返回结果。
I have seen this question: How do I return the response from an asynchronous call? 我已经看到了这个问题: 如何从异步调用返回响应? , and I am trying to implement the callback solution, but something is wrong.
,而我正在尝试实现回调解决方案,但是出了点问题。
This is my code: 这是我的代码:
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;
});
}
Basically, I want to find my current location, and create a HTTP get request to www.skiddle.com to retrieve events near that location. 基本上,我想找到我的当前位置,并向www.skiddle.com创建HTTP get请求以检索该位置附近的事件。
This is how I call the function: 这就是我所谓的函数:
var x = getEventNearYou();
but I seem to have made a mistake, since I am getting the bad request error ( lat
and long
are undefined). 但是我似乎犯了一个错误,因为我遇到了错误的请求错误(未定义
lat
和long
)。
You're using callbacks in a way that undermines their usefulness. 您使用回调的方式会削弱其用途。 You're still writing your code in a synchronous style.
您仍在以同步样式编写代码。 You should continue to reference: How do I return the response from an asynchronous call?
您应该继续参考: 如何从异步调用返回响应?
In the mean time, I'll restructure your code to show how it's done. 同时,我将重组您的代码以显示其完成方式。
As a rule of thumb, if any of the code inside a function uses callbacks, that outer function also needs to accept a callback as a parameter. 根据经验,如果函数内的任何代码使用回调,则该外部函数也需要接受回调作为参数。
If a variable is given a value inside a callback function, it won't be defined outside of the callback function (because asynchronous code always runs after synchronous code). 如果在回调函数中为变量赋值,则不会在回调函数之外定义该变量(因为异步代码始终在同步代码之后运行)。
Don't use async: false
不要使用
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);
}
});
});
}
Then call getEventNearYou
using a callback function: 然后使用回调函数调用
getEventNearYou
:
getEventNearYou(function (events) {
// code which relies on `events` can be called from here
});
Just adding a bit more explanation to 4castle's excellent answer. 只是在4castle的出色答案中添加了更多解释。 In the code you wrote, when your
getLocation()
function is called in Javascript, this is what will happen: 在您编写的代码中,用Javascript调用
getLocation()
函数时,将发生以下情况:
var lat
and var long
are instantiated with values of undefined
. var lat
和var long
用undefined
值实例化。 navigator.geolocation.getCurrentPosition()
is called, which takes a long time to complete. navigator.geolocation.getCurrentPosition()
会花费很长时间。 res
object is instantiated with the current undefined values of lat
and long
. lat
和long
实例化res
对象。 That is, res
is: { "lat": undefined, "long": undefined }
res
是: { "lat": undefined, "long": undefined }
callback
function is called on res
. callback
函数在res
上调用。 This means callback
is called with undefined values for lat
and long
. lat
和long
未定义值callback
。 navigator.geolocation.getCurrentPosition()
finally finishes what it was doing and assigns values to lat
and long
, but by now it is too late because your callback function was already called on the undefined values. navigator.geolocation.getCurrentPosition()
最终完成了所要做的工作,并将值分配给lat
和long
,但是现在为时已晚,因为您的回调函数已经在未定义的值上调用了。 In 4castle's revised code, steps 4-5 are put inside an anonymous callback function to navigator.geolocation.getCurrentPosition()
, which means these lines won't be executed until getCurrentPosition()
is finished getting the position. 在4castle的修改后的代码中,步骤4-5被放置在
navigator.geolocation.getCurrentPosition()
的匿名回调函数中,这意味着直到getCurrentPosition()
完成获取位置后,这些行才会执行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.