You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让JavaScript循环执行完毕后再进入下一轮循环?(Google Maps API场景)

嘿,我看你是想先把所有地点结果都处理妥当,再去跑后续的循环对吧?结合你给的代码,我分两种常见场景给你解决思路:

场景1:确保当前返回的所有results都处理完(不管同步/异步)

如果你的createMarker_Original是纯同步操作(比如只是创建Marker,没涉及异步加载照片这类操作),那原代码的for循环其实已经是把所有results处理完才会退出的。但如果createMarker_Original里有异步逻辑(比如加载照片的请求),那你得用Promise来等待所有异步操作都完成:

改造步骤:

  1. 把createMarker_Original改成返回Promise的函数:
function createMarker_Original(place) {
  return new Promise((resolve, reject) => {
    const photos = place.photos;
    if (!photos) {
      resolve(); // 没照片直接标记完成
      return;
    }

    const placeLoc = place.geometry.location;
    const marker = new google.maps.Marker({
      position: placeLoc,
      map: map // 假设你有全局的map实例
    });

    // 举个例子:如果要异步加载照片缩略图
    photos[0].getUrl({maxWidth: 100}).then(url => {
      // 给Marker加信息窗口之类的操作
      const infowindow = new google.maps.InfoWindow({
        content: `<img src="${url}" alt="${place.name}">`
      });
      marker.addListener('click', () => infowindow.open(map, marker));
      resolve(); // 异步操作完成,标记Promise成功
    }).catch(err => {
      console.error('加载照片出错:', err);
      resolve(); // 就算失败也标记完成,避免卡住后续流程
    });
  });
}
  1. 改造callback_Original,用Promise.all等待所有Marker处理完毕:
async function callback_Original(results, status) {
  if (status === google.maps.places.PlacesServiceStatus.OK) {
    // 把每个地点的处理任务转成Promise,收集起来
    const markerTasks = results.map(place => createMarker_Original(place));
    // 等待所有Promise完成——也就是所有地点都处理完了
    await Promise.all(markerTasks);

    // 到这里,所有结果处理完毕!可以放心执行你的其他循环了
    console.log('所有Marker都搞定了,开始跑后续逻辑');
    // 比如你的其他循环代码:
    // for (let i = 0; i < someArray.length; i++) { ... }
  }
}

场景2:解决“仅返回少量地点”的问题(获取所有分页结果)

如果你的问题是PlacesService只返回了第一页的结果(最多20个),而你需要拿到所有符合条件的地点,那得利用Google Places API的nextPageToken来分页获取所有结果,然后统一处理:

完整改造代码:

// 用来存所有拿到的地点
let allPlaces = [];

// 递归/循环获取所有分页结果的函数
function fetchAllPlaces(service, request) {
  return new Promise((resolve, reject) => {
    service.nearbySearch(request, (results, status, pagination) => {
      if (status === google.maps.places.PlacesServiceStatus.OK) {
        // 把当前页的结果加到总数组里
        allPlaces = [...allPlaces, ...results];
        
        // 如果有下一页,继续获取(注意Google要求必须延迟200ms以上)
        if (pagination && pagination.hasNextPage) {
          setTimeout(() => pagination.nextPage(), 200);
        } else {
          // 所有页都拿完了,返回全部结果
          resolve(allPlaces);
        }
      } else {
        reject(new Error(`获取地点失败:${status}`));
      }
    });
  });
}

// 初始化搜索的入口函数
async function initPlaceSearch() {
  const map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: -33.8688, lng: 151.2195}, // 示例坐标,换成你的
    zoom: 13
  });
  const service = new google.maps.places.PlacesService(map);
  const searchRequest = {
    location: map.getCenter(),
    radius: 5000,
    type: ['restaurant'] // 换成你的搜索条件
  };

  try {
    // 先拿到所有分页的地点结果
    const allResults = await fetchAllPlaces(service, searchRequest);
    console.log(`所有地点获取完成,一共${allResults.length}个`);

    // 统一处理所有结果,创建Marker
    const markerTasks = allResults.map(place => createMarker_Original(place));
    await Promise.all(markerTasks);

    // 到这里,所有结果都处理完了!可以执行你的其他循环了
    console.log('所有Marker创建完成,开始执行后续逻辑');
    // 你的其他循环代码写在这里:
    // for (...) { ... }
  } catch (err) {
    console.error('流程出错:', err);
  }
}

// 调用初始化函数
initPlaceSearch();

// 同步版的createMarker_Original(如果不需要异步,也可以返回Promise方便统一处理)
function createMarker_Original(place) {
  const photos = place.photos;
  if (!photos) {
    return Promise.resolve();
  }

  const placeLoc = place.geometry.location;
  new google.maps.Marker({
    position: placeLoc,
    map: map
  });
  return Promise.resolve();
}

关键提醒:

  • Google Places API要求分页调用必须间隔至少200ms,所以一定要加setTimeout,不然会被拒绝请求
  • 用async/await和Promise可以完美实现“先处理完所有结果,再执行后续循环”的需求
  • 如果你的createMarker_Original是纯同步的,那直接循环处理也没问题,但用Promise统一处理的话,后续扩展异步逻辑更方便

内容的提问来源于stack exchange,提问作者MaeLstroms Stroms

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:27:50