所以我一直在使用 Leaflet.js 在我的家乡创建疫苗接种点的地图,并试图使用路由来找到离用户最近的站点,但是当我登录或尝试时,变量不知何故变得未定义在函数外调用它。我对 js 比较陌生,并且在 python 中使用 folium 时了解了传单。在 python 中,我认为你会声明你正在更改一个全局变量,或者更好地使用 return,但我不确定如何使用 js 和传单库来做到这一点。
var self_lat;
var self_long;
...
var mymap = L.map('mapid').setView([34.7465, -92.2896], 6);
...
function onLocationFound(e) {
console.log(e);
self_lat = e.latitude;
self_long = e.longitude;
L.marker([e.latitude, e.longitude], {icon: home_marker}).bindPopup("YOU ARE HERE!").addTo(mymap);
console.log(typeof(e.latitude))
console.log(typeof(e.longitude))
}
function onLocationError(e) {
alert(e.message);
}
mymap.locate({setView: false, maxZoom: 16});
mymap.on('locationfound', onLocationFound);
mymap.on('locationerror', onLocationError);
...
L.Routing.control({
waypoints: [
L.latLng([self_lat, self_long]),
L.latLng([34.7465, -92.2896])
]
}).addTo(mymap);
答案 0 :(得分:1)
要了解此处的问题,请在 console.log( 'Calling L.Routing.control()', self_lat, self_long )
调用之前添加一个 L.Routing.control()
调用(代码清单中的 ...
)。
你会注意到两件事:
self_lat
和 self_long
将出现在这里undefined
。但为什么?console.log()
在现有 console.log()
调用之前被调用,您将这些值记录到 onLocationFound
函数中。这就是问题的根源。与其他 JavaScript 库和原生 JavaScript 本身中的许多类似函数一样,Leaflet 的 myMap.on( eventName, eventListener )
函数是异步。这意味着 eventListener
- 在本例中为 onLocationFound
- 不会立即调用。稍后调用它,在 myMap.on()
调用本身返回之后。
JavaScript 中的所有异步回调/侦听器函数都以这种方式工作。设置全局变量很少有用,因为问题在于何时运行各种代码。
在不知道其余代码的情况下,我建议的一种可能解决方法是完全去掉 self_lat
和 self_long
变量,并移动 L.Routing.control()
调用 在您的 onLocationFound
函数中,如下所示:
var mymap = L.map('mapid').setView([34.7465, -92.2896], 6);
...
function onLocationFound(e) {
console.log(e);
L.marker(
[e.latitude, e.longitude],
{icon: home_marker}
).bindPopup("YOU ARE HERE!").addTo(mymap);
L.Routing.control({
waypoints: [
L.latLng([e.latitude, e.longitude]),
L.latLng([34.7465, -92.2896])
]
}).addTo(mymap);
}
function onLocationError(e) {
alert(e.message);
}
mymap.locate({setView: false, maxZoom: 16});
mymap.on('locationfound', onLocationFound);
mymap.on('locationerror', onLocationError);
这是一个非常简单的例子,可以帮助说明。我们进行了一个 setTimeout()
调用和三个 console.log()
调用:一个在回调之前,一个在之后,一个在回调内部。单击下面的运行按钮并注意日志消息的顺序:
console.log( 'Before setTimeout' );
setTimeout(
function() {
console.log( 'Inside setTimeout callback' );
},
1 // one millisecond delay
);
console.log( 'After setTimeout returns' );
当然 setTimeout()
这个名字更清楚地表明在调用回调函数之前会有延迟(即使只是一毫秒)。需要注意的是,所有 JavaScript 中的异步回调函数和事件侦听器都是这样工作的。
答案 1 :(得分:0)
如果 self_lat
和 self_long
不是全局变量,则通过只传递 onLocationFound
的原型而失去了上下文,该函数是在 {{1} 的上下文中调用的在这些变量不存在的情况下,要解决这个并将您的回调保持为一个单独的函数,您可以按如下方式调用它:
mymap