javascript - 如何从 Google Places 获取一系列地点的坐标,然后在完成所有操作后使用结果?

标签 javascript node.js promise google-places-api google-places

我有一组地名,例如:

const places = ['King Square, London', 'Empire State Building', 'Great Wall of China'];

我需要一个新的对象数组,其中为地名数组中的每个元素设置了位置,例如:

const places = [
  { name: 'King Square, London', position: { latitude: ..., longitude: ... } },
  ...
];

我认为我必须做这样的事情:

const places = [];

['King Square, London', 'Empire State Building', 'Great Wall of China'].forEach(placeName => {
  axios
  .get(`https://maps.googleapis.com/maps/api/place/textsearch/json?key=GOOGLE_PLACES_API_KEY&query=${placeName}`)
  .then(response => {
    if (!!response && !!response.results && !!response.results[0]) {
      const searchResult = response.results[0];

      if (!!searchResult) {
        axios
          .get(`https://maps.googleapis.com/maps/api/place/details/json?key=GOOGLE_PLACES_API_KEY&placeid=${searchResult.place_id}`)
          .then(response => {
            const placeResult = response.result;

            if (!!placeResult) {
              places.push({ name: placeName, position: placeResult.geometry.location })

但是好像不行。

它应该是什么样子才能填充 places 并在填充后使用数组?在使用它之前,我是否必须使用 Promises 来确保它已被填充?

最佳答案

使用Promise.all() .

更新现有代码的步骤:

  1. 使用 Array.map() 将 promise 存储在数组中而不是 forEach() .
  2. 回拨给map() 返回 promise (即来自 axios.get().then() 的返回值)。
  3. axios.get() 的调用的响应将有一个包含结果的 data 属性,因此使用 response.data.results 而不是 response.results
  4. 再次兑现 promise
  5. 然后在设置了 promises 数组之后,就可以使用 Promise.all() 了:

    const places = [];
    //1 - store promises in an array
    var promises = ['King Square, London', 'Empire State Building', 'Great Wall of China'].map(placeName => {
      return axios //2 - return promise
      .get(`https://maps.googleapis.com/maps/api/place/textsearch/json?key=GOOGLE_PLACES_API_KEY&query=${placeName}`)
      .then(response => {
        //3 - use response.data.results instead of response.results
        if (!!response && !!response.data && !!response.data.results && !!response.data.results[0]) {
          const searchResult = response.data.results[0];
    
          if (!!searchResult) {
            return axios //4 return nested promise
              .get(`https://maps.googleapis.com/maps/api/place/details/json?key=GOOGLE_PLACES_API_KEY&placeid=${searchResult.place_id}`)
              .then(response => {
                const placeResult = response.data.result;
    
                if (!!placeResult) {
                  places.push({ name: placeName, position: placeResult.geometry.location });
                }
              })
          }
        }
      });
    });
    //5 - After promises are done, use the places array
    Promise.all(promises).then(results => {
        console.log('places:', places);
    })
    

输出:

places: [ { name: 'King Square, London',
    position: { lat: 51.52757920000001, lng: -0.0980441 } },
  { name: 'Great Wall of China',
    position: { lat: 40.4319077, lng: 116.5703749 } },
  { name: 'Empire State Building',
    position: { lat: 40.7484405, lng: -73.98566439999999 } } ]

客户端 Javascript 示例

下面是(客户端)JavaScript 的端口。请注意它非常相似,但使用了 StackOverflow API(因为那样不会有 CORS 问题)。

var ranks = [];
var promises = [94, 95].map(badgeId => {
  return axios.get(`https://api.stackexchange.com/2.2/badges/${badgeId}?site=stackoverflow&order=desc&sort=rank&filter=default`)
    .then(response => {
      var responsebadgeId = response.data.items[0].badge_id;
      return axios.get(`https://api.stackexchange.com/2.2/badges/${responsebadgeId}/recipients?site=stackoverflow`)
        .then(response => {
          console.log('pushing rank into array from data: ',response.data.items[0].rank);
          ranks.push(response.data.items[0].rank);
        });
    });
});
Promise.all(promises).then(responses => {
  console.log('promises all callback - ranks:',ranks);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.2/axios.min.js"></script>

关于javascript - 如何从 Google Places 获取一系列地点的坐标,然后在完成所有操作后使用结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45290756/

相关文章:

java - Ratpack 的 Promise.cache 与 ParallelBatch 中的多个下游 promise

javascript - Stripe Charge promise 未能解决

javascript - Webpack 多文件入口捆绑

javascript - 由于错误 800a025e,无法完成操作

javascript - Electron 读取和写入USB驱动器

javascript - 将数学公式转换为 node.js

javascript - 链接两个异步 jQuery 函数时如何完全避开 jQuery promise ?

javascript - 使用Sinonjs stub document.ready

javascript - 从 .js 文件中提取动态菜单并在 html 中显示

node.js - FindOneAndUpdate 不更新带有传入参数的嵌套字段