简体   繁体   English

Google Places Api 批量请求 Javascript

[英]Google Places Api Batch Requests Javascript

So i have heard that there is no real clean way to batch requests referenced here to the GooglePlacesAPI ;所以我听说没有真正干净的方法来批量处理这里引用GooglePlacesAPI请求; understood.明白了。

But there has to be a work around.但必须有一个解决办法。

const retrievePlaces = (google, map, request) => {
  var places = [];
  var newPlaces = []
  var service = new google.maps.places.PlacesService(map);

  return new Promise(function(resolve, reject) {
    service.nearbySearch(request, function(results, status){

    if( status == "OK" ){
      for (var i = 0; i < results.length; i++) {
          var place = results[i];
          places.push(place);
        }
        resolve(places);
      }
    });
  });
}

I use the above function to retrieve my places first (this works fine).我首先使用上面的函数来检索我的位置(这很好用)。 Then I use:然后我使用:

const retrieveDetails = ( google, map, places ) => {

   var gmap = {
     map: map,
     google: google
   };

   var placeIds = places.map(function(place){
     return { placeId: place.place_id }
   });

   var promiseArray = placeIds.map( place => getPlaceDetailsPromise( place, gmap )
                                        .then(  res => ({res}) ) 
                                        .catch( err => ({err}) ) );

   Promise.all(promiseArray)
     .then(results => {
       console.log(results);
   });

 }

and:和:

const getPlaceDetailsPromise = (obj, gmap) => new Promise((resolve, reject) => {
   var service = new gmap.google.maps.places.PlacesService(gmap.map);

   service.getDetails(obj, (place, status) => {
     if (status === google.maps.places.PlacesServiceStatus.OK) {
       console.log(" Status OK", place);
       resolve(place);   
     } else {
       console.log("Not OK");
     }
  });
});

to attempt to retrieve the details for all the places from the PlaceDetailsAPI .尝试从PlaceDetailsAPI检索所有地点的详细信息。 What sucks is that it actually works to a degree, but it always returns only 9 responses and no more.糟糕的是,它实际上在一定程度上有效,但它总是只返回 9 个响应,仅此而已。 furthermore they are out of order.此外,它们出现故障。

Does anyone have any insight on how it might be possible to retrieve the details for each place?有没有人对如何检索每个地方的详细信息有任何见解?

Maps JavaScript API client side services have a per session limits. Maps JavaScript API 客户端服务有每个会话的限制。 This is mentioned in the following section of the documentation:文档的以下部分提到了这一点:

https://developers.google.com/maps/documentation/javascript/geocoding#UsageLimits https://developers.google.com/maps/documentation/javascript/geocoding#UsageLimits

Rate limit applied per user session, regardless of how many users share the same project.每个用户会话应用的速率限制,无论有多少用户共享同一个项目。

The per-session rate limit prevents the use of client-side services for batch requests, such as batch geocoding.每个会话的速率限制会阻止将客户端服务用于批处理请求,例如批处理地理编码。 For batch requests, use the Google Maps Geocoding API web service.对于批量请求,请使用 Google Maps Geocoding API Web 服务。

Unfortunately, documentation doesn't include this notice in the places library part of the documentation, but it works the same.不幸的是,文档并没有在文档的地方库部分包含这个通知,但它的工作原理是一样的。

As far as I know, initially you have a bucket of 10 requests.据我所知,最初您有一桶 10 个请求。 Once the bucket is empty request is denied.一旦桶为空,请求就会被拒绝。 The bucket is refilled at the rate 1 request per second.存储桶以每秒 1 个请求的速率重新填充。 So, you have to throttle your places details requests in order to stay within allowed per session limits.因此,您必须限制您的地点详细信息请求,以保持在每个会话允许的限制内。 Alternatively, you can try to implement batch places requests on server side where you will have 50 queries per second (QPS) limit.或者,您可以尝试在服务器端实现批量放置请求,您将拥有每秒 50 个查询 (QPS) 的限制。

Thanks @xomena, and for anybody else that may stumble upon this question there is a way to do it and it involves what @xomena mentioned before.谢谢@xomena,对于可能偶然发现这个问题的任何其他人,有一种方法可以做到这一点,它涉及@xomena 之前提到的内容。 It is a little dirty and probably extremely inefficient but does what i need it to do.它有点脏,可能效率极低,但可以做我需要它做的事情。

I ended up doing a little ajax/curl inception to solve my issue and to get around the CORS issues i was having as well.我最终做了一些 ajax/curl inception 来解决我的问题并解决我遇到的 CORS 问题。 I made a server side proxy that takes the formatted google api request uri ( sent via ajax from one of my functions ) and returns the details object.我制作了一个服务器端代理,它采用格式化的 google api 请求 uri(通过我的一个函数通过 ajax 发送)并返回详细信息对象。

After that everything worked like a charm.在那之后,一切都像魅力一样。 Updated Code is as follows.更新代码如下。

const retrievePlaces = (google, map, request) => {
  var places = [],
      newPlaces = [],
      service = new google.maps.places.PlacesService(map);

  return new Promise(function(resolve, reject) {
    service.nearbySearch(request, function(results, status){
      if( status == "OK" ){
        for (var i = 0; i < results.length; i++) {
          var place = results[i];
          places.push(place);
        }
        resolve(places);
      }
     });
  });
}

const retrieveDetails = (google, map, places, api) => {

  var gmap = { map: map, google: google, api_key: api },
      placeDetails = [],
      placeIds = places.map(getPlaceIds),
      promiseArray = placeIds.map(getPlaceDetails);

  function getPlaceIds(place){
    return { placeId: place.place_id }
  }

  function getPlaceDetails(place){
    getPlaceDetailsPromise( place, gmap )
      .then(  res => ({res}) ) 
      .catch( err => ({err}) );
  }

  return Promise.all(promiseArray);

}

const getPlaceDetailsPromise = ( obj, gmap ) => new Promise((resolve, reject) => {

  var url = `https://maps.googleapis.com/maps/api/place/details/json?placeid=${obj.placeId}&key=${gmap.api_key}`,
      qsObj = Qs.parse({ url: url }),
      qsString = Qs.stringify(qsObj),
      headerConfig = { 
        headers: { 
          "Content-Type": "application/x-www-form-urlencoded" 
        } 
      };

  function resolveDetails(res){
    var result = res.data;
    resolve($.parseJSON(result));
  }

  axios.post('/a/random/path', qsString, headerConfig ).then(resolveDetails);

});

And then the proxy in php:然后是php中的代理:

<?php 
 /* proxy.php */
 $url = $_POST["url"];

 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 $result = curl_exec ($ch);
 curl_close ($ch);

 $result = json_encode($result);

 echo $result;

 die();
?>

Of course this won't work if you plug and played it into your code but the idea is there.当然,如果您将它插入并播放到您的代码中,这将不起作用,但这个想法就在那里。 If anybody finds a better way I'd love to see how you did it, it would be good shit to know in the future.如果有人找到更好的方法,我很想看看你是如何做到的,将来知道这将是件好事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM