如何用Google API与JavaScript在循环中下载单个合并JSON文件
解决Google Places API数据合并后单次下载问题
问题出在哪
你现在的代码每次API返回数据后,都会在placeResults里触发下载,还每次把之前的内容追加到文本区域再生成文件,结果就是生成好几个一模一样的完整数据文件。根本原因是下载逻辑写在了单个请求的回调里,没等所有请求都跑完就开始下载了。
怎么改
- 弄个全局数组存所有地点的数据
- 记着已经完成了多少个请求,等所有请求都做完再合并数据、触发下载
- 把下载的代码从单个请求的回调里挪出来,放到所有请求完成后的处理函数里
修改后的完整代码
function initMap() { //====Array of Google Place IDs=====// var placeid_list = [{ "placeid": 'ChIJryijc9s0K4gRG9aU7SDTXdA', }, { "placeid": 'ChIJaZ6Hg4iAhYARxTsHnDFJ9zE', }, { "placeid": 'ChIJl64IQXrYzUwR8CVOTRf_h3o', }, { "placeid": 'ChIJBTMkuph-zkwR9oEF8Nv3Z0o', }, { "placeid": 'ChIJ4QbSBj8IzkwRGi0ILu03_VA', }, { "placeid": 'ChIJc2nSALkEdkgRkuoJJBfzkUI', }, { "placeid": 'ChIJmzrzi9Y0K4gRgXUc3sTY7RU', }]; // 存储所有获取到的地点数据 const allPlaceData = []; // 跟踪已完成的请求数量 let completedRequests = 0; function setPlaces() { const json = placeid_list; //====Loop for Place IDs=====// for (var i = 0, length = json.length; i < length; i++) { var data = json[i]; createPlace(data); } } function createPlace(data) { var service = new google.maps.places.PlacesService(document.getElementById("placeResults")); service.getDetails({ placeId: data.placeid, fields: [ "name", "formatted_address", "place_id", "geometry", "type", "formatted_phone_number", "rating", "reviews", "website", "url", "photos", "opening_hours", "price_level" ], }, function (result, status) { if (status != google.maps.places.PlacesServiceStatus.OK) { console.error(status); // 请求失败也记为完成,避免卡住后续流程 completedRequests++; checkAllDone(); return; } // 将当前地点数据加入数组 allPlaceData.push(result); completedRequests++; checkAllDone(); }); } function checkAllDone() { // 所有请求完成后执行合并和下载 if (completedRequests === placeid_list.length) { mergeAndDownload(); } } function mergeAndDownload() { // 将所有数据转为JSON格式 const jsonStr = JSON.stringify(allPlaceData, null, 2); // 展示到页面(可选) document.getElementById("placeResults").textContent = jsonStr; //====生成并下载JSON文件=====// const a = document.createElement("a"); a.href = URL.createObjectURL(new Blob([jsonStr], { type: "application/json" })); a.setAttribute("download", "all_places_data.json"); document.body.appendChild(a); a.click(); document.body.removeChild(a); } setPlaces(); } window.initMap = initMap;
关键改动点
- 新增
allPlaceData数组,专门收集每个API返回的地点数据 - 新增
completedRequests变量,跟踪已完成的请求(失败的请求也会被计数,避免流程卡住) - 新增
checkAllDone函数,判断所有请求是否完成,完成后触发合并下载逻辑 - 下载逻辑移到
mergeAndDownload函数,仅在所有数据收集完成后执行一次 - 把之前的
Object.assign(result)改成直接push到数组,因为你需要的是所有地点的数组集合,而非单个对象合并 - 下载文件名改为
all_places_data.json,更清晰区分文件内容
这么改完之后,代码会等待所有Google Places API请求完成,把所有地点数据合并成一个JSON数组,然后只触发一次下载,就能拿到包含所有内容的单个JSON文件了。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

