2017-09-05 79 views
0

我试图创建一组函数,使用谷歌地图地理编码器API将一组地址转换为经纬度值。谷歌地图地理编码器API的承诺

目前,我已经成功地将地址转换为lat long值,但函数在返回之前完全执行。我知道这一点,因为它在之后记录正确的经纬度值之前抛出未定义的错误。

我听说javascripts承诺可以解决这类问题,所以我做了一点研究,但似乎没有帮助解决问题。如果我以错误的方式解决这个问题,我对承诺的新承诺如此反感。

Here`s相关代码

function getPoints(geocoder,map) { 
     let locationData = []; 
     let latValue; 
     for(let i = 0; i < addressData.length; i++){ 
      let getLatLong = new Promise(function(resolve,reject){ 
       latValue = findLatLang(addressData[i].location, geocoder, map); 
       if(latValue!=undefined){ 
         resolve(latValue()); 
       } else { 
         reject(); 
       } 
      }); 
      getLatLong.then(function(){ 
       console.log(latValue); 
       //returns a GMap latLng Object. 
       locationData.push(new google.maps.LatLng(latValue[0],latValue[1])); 
      }) 
     } 
     return locationData; 
    } 

function findLatLang(address, geocoder, mainMap) { 
     geocoder.geocode({'address': address}, function(results, status) { 
      if (status === 'OK') { 
       console.log(results); 
       return [results[0].geometry.location.lat , results[0].geometry.location.lng]; 
      } else { 
       alert('Couldnt\'t find the location ' + address); 
       return; 
      } 
     }) 
    } 

预先感谢任何帮助或指针,你将有!

+0

@Jaya getPoints for循环中有一个叫做getLatLong的承诺。我再次只观看了一些视频,所以我可能会使用这个完全错误的视频。 –

+0

哎呀刚刚看到了。你也有一个在循环内的承诺,循环会在它执行你的'then'之前迭代。所以你需要修改你的代码。让我提供样本 – Jaya

+0

将你所有的承诺推到一个数组中,然后等待它们,但是你希望它是并行处理还是一个接一个处理? – Jaya

回答

2

您的主要问题是geocoder.geocode()是异步的并需要回调。您将函数传递给回调函数,但将返回值视为将从主函数findLatLang()返回,但不会。目前findLatLang()什么也没有返回。

findLatLang()是你应该有承诺,从函数返回它:

function findLatLang(address, geocoder, mainMap) { 
    return new Promise(function(resolve, reject) { 
     geocoder.geocode({'address': address}, function(results, status) { 
      if (status === 'OK') { 
       console.log(results); 
       resolve([results[0].geometry.location.lat , results[0].geometry.location.lng]); 
      } else { 
       reject(new Error('Couldnt\'t find the location ' + address)); 
      } 
    }) 
    }) 
} 

在循环中getPoints()然后,你可以收集这些承诺转化为一个阵列和阵列,这将给上调用Promise.all()你的价值观一旦所有承诺已经解决:

function getPoints(geocoder,map) { 
    let locationData = []; 
    let latValue; 
    for(let i = 0; i < addressData.length; i++){ 
     locationData.push(findLatLang(addressData[i].location, geocoder, map)) 
    } 
    return locationData // array of promises 
} 

var locations = getPoints(geocoder,map) 

Promise.all(locations)  
.then(function(returnVals){ 
     // you should have return values here when 
     // all promises have rsolved 
      console.log(returnVals); 
}) 

目前尚不清楚其中addressData是从哪里来的 - 你在函数中使用它,但它不是在任何地方被传递。

+0

addressData是我用于测试的全局json数据变量!我现在通过阅读这个问题来理解它是如何工作的,然后我让你知道它是否有效!感谢评论:) –

+0

真棒!这与一点点调整工作! Promise.all函数似乎将在未来非常有用 –