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

如何在JS的fetch循环调用中使用首次fetch的返回结果?

解决Google Maps API二次调用的异步问题

先给你指出原代码里的几个致命问题:

  • response.json 是方法,必须调用(加括号response.json())才会返回解析JSON的Promise,你现在只是传了方法引用,根本没执行解析
  • 嵌套循环里的fetch会陷入回调地狱,不仅代码难维护,还没法保证请求完成顺序,也没法统一处理所有请求的结果
  • 没有错误处理,fetch遇到4xx/5xx这类HTTP错误不会自动抛出异常,会默默继续执行,出问题根本查不到原因

下面是用async/await+Promise.all()重构后的可运行代码,逻辑清晰,能正确批量处理二次请求:

// 把整个逻辑封装在async函数里
async function fetchAndRenderPlaces() {
  try {
    // 第一步:调用附近搜索API获取地点列表
    const nearbyResponse = await fetch(googleMapsApi);
    // 检查请求是否成功,失败就抛出错误
    if (!nearbyResponse.ok) throw new Error(`附近搜索请求失败: ${nearbyResponse.status}`);
    const nearbyData = await nearbyResponse.json();

    // 第二步:生成所有详情请求的Promise数组
    const detailRequests = nearbyData.results.map(async (place) => {
      // 先提取第一次请求里的基础数据
      const basicInfo = {
        name: place.name,
        address: place.formatted_address,
        location: place.geometry.location
        // 其他你需要的基础字段
      };

      // 用Place ID发起二次请求获取详情
      const detailResponse = await fetch(`你的详情API地址?place_id=${place.place_id}&key=你的API密钥`);
      if (!detailResponse.ok) throw new Error(`获取${place.name}详情失败: ${detailResponse.status}`);
      const detailData = await detailResponse.json();

      // 合并基础数据和详情数据
      return {
        ...basicInfo,
        phone: detailData.result.formatted_phone_number,
        website: detailData.result.website,
        rating: detailData.result.rating
        // 其他你需要的详情字段
      };
    });

    // 等待所有详情请求完成,拿到所有合并后的完整数据
    const allPlaces = await Promise.all(detailRequests);

    // 第三步:统一渲染所有数据到页面
    allPlaces.forEach(place => {
      // 这里写你的DOM渲染逻辑,比如创建卡片插入页面
      const placeCard = document.createElement('div');
      placeCard.innerHTML = `
        <h3>${place.name}</h3>
        <p>${place.address}</p>
        <p>电话: ${place.phone || '无'}</p>
        <p>官网: ${place.website ? `<a href="${place.website}">点击访问</a>` : '无'}</p>
      `;
      document.body.appendChild(placeCard);
    });

  } catch (err) {
    // 统一捕获所有错误,方便调试
    console.error('处理请求时出错:', err.message);
  }
}

// 执行函数
fetchAndRenderPlaces();

核心逻辑说明:

  1. async/await:把异步代码写成同步风格,彻底摆脱嵌套回调的混乱,逻辑一目了然
  2. Promise.all():一次性发起所有二次请求,等待全部完成后再处理结果,比循环里逐个等效率高,也能保证所有数据都准备好再渲染
  3. 错误集中处理:用try/catch包裹所有异步操作,任何一步出错都会进入catch块,方便定位问题
  4. 数据合并:把第一次和第二次请求的数据合并成完整对象,再统一渲染,避免分散的DOM操作

原代码失效的根本原因:

JavaScript的异步特性会让循环里的fetch立即执行,不会等上一个请求完成,导致你可能在数据还没返回就试图渲染;加上response.json没加括号,根本没解析JSON,后续代码拿不到有效数据,自然没法正常运行。

内容的提问来源于stack exchange,提问作者Josh Watkins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:52:57