无法在循环中添加Google标记 [英] Unable to add Google markers inside a loop

查看:63
本文介绍了无法在循环中添加Google标记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So, I'm getting addresses from my firestore database, converting them to coordinates, then trying to add markers based on each set of coordinates. I'm able to add markers outside the loop, but not inside.

谢谢

    //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}
    });


推荐答案

我的第一个猜测是你是在循环外使用 标记,例如在对maps API的调用中。这是行不通的,因为数据是从Firestore异步加载的,并且此时数据还不可用。

My first guess is that you're using markers outside of the loop, for example in a call to the maps API. That won't work, as the data is loaded from Firestore asynchronously, and the data isn't available yet at that point.

了解异步加载方式的最简单方法是使用某些方法。放置正确的日志记录语句:

The easiest way to understand how asynchronous loading works is with some well placed logging statements:

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");

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

Now when you run this code, the logging output will be:



  1. 调用数据库之前

  1. Before calling database

调用数据库之后

Got数据库结果,调用地理编码API

Got database results, calling geocode API

Got地理编码结果

地理编码结果

...

这可能不是您所期望的,因为代码没有按照在文件中的存储顺序执行。但是由于异步API的特性,它完全可以按预期工作。并且,它解释了为什么如果您对地图的调用接近日志记录语句 4。,为什么不将数据库中的位置添加到地图中:在运行时,没有数据

This is probably not what you expected, as the code doesn't execute in the order in which you have it in your file. But it is completely working as intended, due to the nature of asynchronous APIs. And, it explains why locations from the database aren't added to maps, if your call to maps is near logging statement 4.: by the time that runs, no data has been loaded from the database yet, and the geocoding hasn't been done yet either.

任何需要数据库中数据的代码都应放在 then 回调。使事情变得更复杂:由于您还希望完成所有的地理查找,因此您只想在所有嵌套的 then()调用发生后将标记添加到地图中。

Any code that needs the data from the database should be inside the then callback. To make things more complex: since you also want all geolookups to have been completed, you only want to add the markers to maps, once all the nested then() calls have happened.

要执行此操作,可以使用 Promise.all ,它可以解析单个 then()一旦解决了其他多个 then()调用。

To do this you can use Promise.all, which resolves a single then() once multiple other then() calls have been resolved.

将所有这些结合起来,将导致代码看起来像这样:

Combining all of this, leads to code that should look something like this:

//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
});

这篇关于无法在循环中添加Google标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆