如何捕获Google Maps AutocompletionService网络异常并展示友好提示
处理Google Maps地址搜索离线异常的方案
问题原因
你的try-catch无法捕获离线时的网络错误,是因为Google Maps Autocomplete控件内部的异步请求在Google官方脚本的执行上下文中运行,不属于你代码的try-catch覆盖范围,这类跨上下文的异步异常无法被常规同步捕获逻辑捕捉。
解决方案
以下是几种可行的处理方式,可根据需求组合使用:
1. 监听浏览器在线状态,提前拦截
通过浏览器的navigator.onLine属性和online/offline事件,实时检测网络状态,在用户输入地址前直接提示离线状态:
// 初始化在线状态标记 let isOnline = navigator.onLine; // 监听网络状态变化 window.addEventListener('online', () => { isOnline = true; // 隐藏离线提示(需提前在页面中添加对应元素) document.getElementById('offline-alert')?.classList.add('hidden'); }); window.addEventListener('offline', () => { isOnline = false; // 显示离线提示 document.getElementById('offline-alert')?.classList.remove('hidden'); }); // 监听地址输入框的输入事件 document.getElementById('autocomplete').addEventListener('input', () => { if (!isOnline) { alert('当前处于离线状态,无法搜索地址,请检查网络连接'); document.getElementById('autocomplete').value = ''; // 清空输入 } });
2. 监听Autocomplete控件的错误事件
Google Maps Places控件支持error事件监听,可捕获API返回的各类错误(包括网络异常):
在你的initAutocomplete函数中,初始化Autocomplete后添加以下代码:
// 监听Autocomplete错误事件 google.maps.event.addListener(autocomplete, 'error', (error) => { console.error('地址搜索错误:', error); // 判断是否为网络相关错误 if (error.status === 'NETWORK_ERROR' || error.message.includes('ERR_INTERNET_DISCONNECTED')) { alert('网络连接异常,无法获取地址信息,请检查网络后重试'); } else { alert(`地址搜索失败:${error.message}`); } });
3. 手动调用AutocompletionService,完全控制请求逻辑
放弃Autocomplete控件的自动请求,改用AutocompletionService手动发起地址预测请求,这样可以完全控制请求的异常处理:
window.initAutocomplete = function (searchText, compoent, name) { try { const input = document.getElementById('autocomplete'); const placeOptions = { fields: ["formatted_address", "address_components", "geometry", "name"], types: ["premise"], componentRestrictions: { country: ['uk'] } }; // 初始化地址预测服务 const autocompleteService = new google.maps.places.AutocompletionService(); // 初始化详情查询服务(用于点击预测结果后获取完整地址) const placesService = new google.maps.places.PlacesService(document.createElement('div')); // 防抖处理输入事件,避免频繁请求 let debounceTimer; input.addEventListener('input', () => { clearTimeout(debounceTimer); const query = input.value.trim(); const resultsList = document.getElementById('predictions-list'); if (!query) { resultsList.innerHTML = ''; return; } if (!navigator.onLine) { alert('当前离线,无法搜索地址'); resultsList.innerHTML = ''; return; } debounceTimer = setTimeout(() => { autocompleteService.getPlacePredictions({ input: query, ...placeOptions }, (predictions, status) => { if (status !== google.maps.places.PlacesServiceStatus.OK) { if (status === google.maps.places.PlacesServiceStatus.NETWORK_ERROR) { alert('网络连接失败,请检查网络'); } else { alert(`无法获取地址建议:${status}`); } resultsList.innerHTML = ''; return; } // 渲染预测结果列表 resultsList.innerHTML = predictions.map(prediction => ` <li data-place-id="${prediction.place_id}">${prediction.description}</li> `).join(''); // 绑定结果点击事件,获取完整地址详情 resultsList.querySelectorAll('li').forEach(item => { item.addEventListener('click', () => { const placeId = item.dataset.placeId; placesService.getDetails({ placeId: placeId, fields: placeOptions.fields }, (place, status) => { if (status !== google.maps.places.PlacesServiceStatus.OK) { alert('获取地址详情失败'); return; } // 处理地址详情,和原place_changed逻辑一致 input.value = place.formatted_address; // 后续处理纬度、地址组件等逻辑 }); }); }); }); }, 300); }); // 保留原有的marker、infowindow等逻辑(按需调整) const infowindow = new google.maps.InfoWindow(); const infowindowContent = document.getElementById('infowindow-content'); infowindow.setContent(infowindowContent); const marker = new google.maps.Marker({ anchorPoint: new google.maps.Point(0, -29), }); } catch (error) { console.log(error.message); alert('地址搜索初始化失败:' + error.message); } };
推荐组合
优先使用方案1提前告知用户离线状态,同时结合方案2捕获控件内部的意外错误;如果需要更灵活的请求控制,可采用方案3完全自定义搜索逻辑。
内容的提问来源于stack exchange,提问作者ramesh
相关产品推荐
相关产品推荐

