陷入javascript变量闭包
我只是想给lat和lon变量分配position.coords.latitude和longitude,但似乎我遗漏了一些东西,因为控制台总是说lat-lon是未定义的陷入javascript变量闭包,javascript,Javascript,我只是想给lat和lon变量分配position.coords.latitude和longitude,但似乎我遗漏了一些东西,因为控制台总是说lat-lon是未定义的 function init() { var lat; var lon; if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) {
function init()
{
var lat;
var lon;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position)
{
lat = position.coords.latitude;
lon = position.coords.longitude;
});
}
console.log(lat);
console.log(lon);
}
问题是,当您像最初一样使用
var
定义变量时,它们的值是未定义的。现在,当您调用getCurrentPosition
函数时,它可能是异步的,这意味着console.log
在您实际分配任何值之前被调用。尝试以下更改
function init()
{
var lat;
var lon;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position)
{
lat = position.coords.latitude;
lon = position.coords.longitude;
// Log them in the callback function
console.log(lat);
console.log(lon);
});
}
}
由于您希望在获得coords后执行实际代码,因此下面介绍如何更改init函数以适应异步体系结构
// New function argument callbackFn - the function to call after
// coords are loaded
function init(callbackFn)
{
// Removed local variables, no need for them here
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position)
{
var lat = position.coords.latitude;
var lon = position.coords.longitude;
// This will be logged after the async call completes, probably after
// the console.log call below
console.log("finished async call");
// Execute the callback with coords
callbackFn(lat, lon);
});
}
// This will be called as soon as JS steps over previous lines,
// but before the asynchronous request has completed
console.log("finished init");
}
让我们假设您的实际程序是在执行名为“以纬度和经度开始”的函数时开始的。在这种情况下,您可以使用以下命令启动程序:
function start(latitude, longitude) {
// ... SNIP ... DO SOMETHING COOL
}
init(start);
问题是,当您像最初一样使用
var
定义变量时,它们的值是未定义的。现在,当您调用getCurrentPosition
函数时,它可能是异步的,这意味着console.log
在您实际分配任何值之前被调用。尝试以下更改
function init()
{
var lat;
var lon;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position)
{
lat = position.coords.latitude;
lon = position.coords.longitude;
// Log them in the callback function
console.log(lat);
console.log(lon);
});
}
}
由于您希望在获得coords后执行实际代码,因此下面介绍如何更改init函数以适应异步体系结构
// New function argument callbackFn - the function to call after
// coords are loaded
function init(callbackFn)
{
// Removed local variables, no need for them here
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position)
{
var lat = position.coords.latitude;
var lon = position.coords.longitude;
// This will be logged after the async call completes, probably after
// the console.log call below
console.log("finished async call");
// Execute the callback with coords
callbackFn(lat, lon);
});
}
// This will be called as soon as JS steps over previous lines,
// but before the asynchronous request has completed
console.log("finished init");
}
让我们假设您的实际程序是在执行名为“以纬度和经度开始”的函数时开始的。在这种情况下,您可以使用以下命令启动程序:
function start(latitude, longitude) {
// ... SNIP ... DO SOMETHING COOL
}
init(start);
我可以想象navigator.geolocation.getCurrentPosition()是异步的,因此在您尝试写入控制台时它不会执行 尝试将控制台写入移动到回调函数中:
function init()
{
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position)
{
var lat = position.coords.latitude;
var lon = position.coords.longitude;
console.log(lat);
console.log(lon);
});
}
}
我可以想象navigator.geolocation.getCurrentPosition()是异步的,因此在您尝试写入控制台时它不会执行 尝试将控制台写入移动到回调函数中:
function init()
{
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position)
{
var lat = position.coords.latitude;
var lon = position.coords.longitude;
console.log(lat);
console.log(lon);
});
}
}
getCurrentPosition是异步执行的吗?(setTimeout/setInterval/AJAX)是异步的。抱歉,我是noob,但我如何才能使它同步?当没有参数时:除了修改脚本之外,没有其他方法。但这可能是第三方库,对吧?@AssadUllah:你不想让它同步。您应该简单地学习使用异步代码。这意味着依赖于响应的所有代码都是从回调函数调用的。如果需要,您可以让
init()
接受函数作为参数,让回调调用该函数,并将lat
和lon
传递给它。getCurrentPosition是否异步执行?(setTimeout/setInterval/AJAX)是异步的。抱歉,我是noob,但我如何才能使它同步?当没有参数时:除了修改脚本之外,没有其他方法。但这可能是第三方库,对吧?@AssadUllah:你不想让它同步。您应该简单地学习使用异步代码。这意味着依赖于响应的所有代码都是从回调函数调用的。如果需要,您可以让init()
接受一个函数作为参数,并让回调函数调用该函数,然后将lat
和lon
传递给它。是的,函数getCurrentPosition是异步的,但我想要实现的是将坐标分配给lat和lon变量,以便我可以使用它们afterwards@AssadUllah异步体系结构是Javascripts的基本思想之一,试图强制它同步执行是一个坏主意,所以您必须始终使用回调函数。用示例更新了答案。@AssadUllah如果您愿意,您也可以将变量写为全局变量,方法是将var-lat
更改为window.lat
(或者只是lat
,但我建议使用window
以防止混淆)。但是请记住,在异步回调返回之前,仍然不能使用它们,所以你仍然应该有一些我展示过的东西。是的,函数getCurrentPosition是异步的,但是我想要实现的是将坐标分配给lat和lon变量,这样我就可以使用它们了afterwards@AssadUllah异步体系结构是Javascripts的基本思想之一,试图强制它同步执行是一个坏主意,所以您必须始终使用回调函数。用示例更新了答案。@AssadUllah如果您愿意,您也可以将变量写为全局变量,方法是将var-lat
更改为window.lat
(或者只是lat
,但我建议使用window
以防止混淆)。但是请记住,在异步回调返回之前,您仍然不能使用它们,因此您应该仍然可以使用我所展示的内容。是的,函数getCurrentPosition是异步的,但我想要实现的是将坐标分配给lat和lon变量,以便我可以在以后使用它们。这很好,只需在全局范围内声明lat和lon,并在回调中分配它们的值。您可能需要从回调方法引导任何进一步的逻辑-可能让它调用一个名为handlegeLocation()的方法或类似的方法。是的,函数getCurrentPosition是异步的,但我想要实现的是将坐标分配给lat和lon变量,以便我以后可以使用它们。这很好,只需在全局范围内声明lat和lon,并在回调中分配它们的值。您可能需要从回调方法中引导任何进一步的逻辑-可能让它调用名为handlegeLocation()的方法或类似的方法。