无法在循环中添加Google标记



因此,我从firestore数据库中获取地址,将它们转换为坐标,然后尝试根据每组坐标添加标记。我可以在循环外添加标记,但不能在循环内添加。

谢谢

//Convert addresses to coords
//Fetch all addresses from db
db.collection('specials').get()
.then(snapshot => {
snapshot.forEach(special => {
//Set location
var location = special.data().address;
//Get geocode info
axios.get('https://maps.googleapis.com/maps/api/geocode/json?components=country:NZ|country:AU',{
params:{
address:location, 
key:'************************************',  
}
})
.then(function(response){
//Geometry
markerLat = response.data.results[0].geometry.location.lat;
markerLng = response.data.results[0].geometry.location.lng; 
//console.log("Lat:" + markerLat + " Lng:" + markerLng);
//Doesn't work inside the loop
markers.push({
coords:{lat: markerLat, lng: markerLng}
});
})
});
})
//Works outside the loop
markers.push({
coords:{lat: -36.8585, lng: 174.7833}
});

我的第一个猜测是您在循环之外使用markers,例如在对映射API的调用中。这是行不通的,因为数据是从Firestore异步加载的,而且此时数据还不可用。

了解异步加载如何工作的最简单方法是使用一些放置良好的日志记录语句:

console.log("1. Before calling database");
db.collection('specials').get()
.then(snapshot => {
console.log("2. Got database results, calling geocode API");
snapshot.forEach(special => {
var location = special.data().address;
axios.get('https://maps.googleapis.com/maps/api/geocode/json?components=country:NZ|country:AU',{
params:{ address:location,  key:'********' }
})
.then(function(response){
console.log("3. Got geocode result");
})
});
})
console.log("4. After calling database");

现在,当您运行此代码时,日志输出将是:

  1. 调用数据库之前

  2. 调用数据库后

  3. 获取数据库结果,调用地理编码API

  4. 得到地理编码结果

  5. 得到地理编码结果

。。。

这可能不是您所期望的,因为代码没有按照文件中的顺序执行。但由于异步API的性质,它完全按预期工作。而且,它解释了为什么数据库中的位置没有添加到地图中,如果您对地图的调用接近日志记录语句4.:到运行时,还没有从数据库加载任何数据,地理编码也还没有完成。

任何需要数据库数据的代码都应该在then回调中。让事情变得更复杂:因为您还希望所有的地理查找都已完成,所以您只希望在所有嵌套的then()调用完成后将标记添加到映射中。

为此,您可以使用Promise.all,一旦解析了多个其他then()调用,它就会解析单个then()

将所有这些结合在一起,可以得到如下代码:

//Fetch all addresses from db
db.collection('specials').get()
.then(snapshot => {
// Get all addresses from the documents
return snapshot.docs.map(doc => doc.data().address);
})
.then(addresses => {
// Geocode all addresses, to get coordinates
return Promise.all(addresses.map(location => {
return axios.get('https://maps.googleapis.com/maps/api/geocode/json?components=country:NZ|country:AU',{
params:{
address:location, 
key:'************************************',  
}
})
});
})
.then(locations => {
// Convert all geometry into markers
return locations.map(response => {
markerLat = response.data.results[0].geometry.location.lat;
markerLng = response.data.results[0].geometry.location.lng; 
return  {
coords:{lat: markerLat, lng: markerLng}
});
});
})
.then(markers => {
// TODO: call the maps API and add the markers
});

如果您的代码在现代JavaScript环境中运行,您可以使用async/await使上述读取更加正常。

//Fetch all addresses from db
let snapshot = await db.collection('specials').get()
// Get all addresses from the documents
let addresses = snapshot.docs.map(doc => doc.data().address);
// Geocode all addresses, to get coordinates
let locations = await Promise.all(addresses.map(location => {
return axios.get('https://maps.googleapis.com/maps/api/geocode/json?components=country:NZ|country:AU',{
params:{
address:location, 
key:'************************************',  
}
})
});
// Convert all geometry into markers
let markers = locations.map(response => {
markerLat = response.data.results[0].geometry.location.lat;
markerLng = response.data.results[0].geometry.location.lng; 
return  {
coords:{lat: markerLat, lng: markerLng}
});
});
// TODO: call the maps API and add the markers

正如您在这里看到的,结构基本相同,我们只是使用await关键字取消了then块。

相关内容

  • 没有找到相关文章

最新更新