JavaScript点击按钮触发fetch请求需多次点击才生效的问题求助
问题解决:点击按钮一次获取异步请求数据
你的问题核心是异步函数调用时没有等待请求完成就执行后续代码,加上用全局变量存储请求结果,导致每次点击都在用上一次的旧数据,出现滞后现象。以下是修正方案:
错误原因拆解
- 你给
getReqVonPlz、getReqNachPlz加了async/await,但在点击事件里调用时没加await,这意味着代码会直接跳过请求,继续执行console.log(vonJson...),此时请求还没返回,vonJson还是上一次的旧值(第一次点击时是undefined)。 - 全局变量
vonJson、nachJson、kilometer会保留之前的请求结果,导致每次点击都滞后一步。
修正后的完整代码
document.addEventListener('DOMContentLoaded', function() { const vonPlz = document.getElementById("vonPlz"); const nachPlz = document.getElementById("nachPlz"); const vonOrt = document.getElementById("vonOrt"); const nachOrt = document.getElementById("nachOrt"); const km = document.getElementById("km"); const sendBtn = document.getElementById("sendBtn"); // 把点击事件改成async函数,内部可以用await sendBtn.addEventListener('click', async function() { try { // 等待两个GET请求完成,直接获取返回的JSON数据 const vonJson = await getReqVonPlz(vonPlz.value); const nachJson = await getReqNachPlz(nachPlz.value); // 提取坐标 const vonLat = vonJson[0].lat; const vonLon = vonJson[0].lon; const nachLat = nachJson[0].lat; const nachLon = nachJson[0].lon; // 等待POST请求完成,获取公里数 const kilometer = await postReqKm(vonLat, vonLon, nachLat, nachLon); // 更新DOM console.log(vonJson[0].display_name); console.log(nachJson[0].display_name); console.log(kilometer); vonOrt.innerHTML = vonJson[0].display_name; nachOrt.innerHTML = nachJson[0].display_name; km.innerHTML = (kilometer / 1000).toFixed(2); // 转成公里并保留两位小数 } catch (error) { // 处理请求失败的情况,比如输入无效PLZ、网络错误 console.error('请求出错:', error); alert('数据获取失败,请检查输入或网络连接'); } }); }); // 修改函数,直接返回请求结果,不再用全局变量 async function getReqVonPlz(plz){ const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&country=de&postalcode=${plz}`, { method: "GET", headers: { "Content-type": "application/json; charset=UTF-8" } }); return await response.json(); } async function getReqNachPlz(plz){ const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&country=de&postalcode=${plz}`, { method: "GET", headers: { "Content-type": "application/json; charset=UTF-8" } }); return await response.json(); } async function postReqKm(vonLat, vonLon, nachLat, nachLon){ const response = await fetch("https://api.openrouteservice.org/v2/directions/driving-car", { method: "POST", body: JSON.stringify({ coordinates: [[vonLon,vonLat],[nachLon,nachLat]], }), headers: { "Content-type": "application/json; charset=UTF-8", "Authorization": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", } }); const json = await response.json(); return json.routes[0].summary.distance; }
关键修改点
- 点击事件改为async函数:只有在async函数内部才能使用
await,确保请求完成后再执行后续代码。 - 异步函数直接返回结果:去掉全局变量,让函数返回请求得到的JSON或公里数,调用时通过
await接收,避免旧数据干扰。 - 添加错误处理:用
try/catch包裹异步操作,防止请求失败导致页面崩溃,同时给用户友好提示。 - 模板字符串优化URL:把拼接URL改成模板字符串,更易读。
- 公里数格式处理:把返回的米数转成公里并保留两位小数,显示更合理。
这样修改后,点击一次按钮就能按顺序完成所有请求,并正确更新DOM内容。
内容的提问来源于stack exchange,提问作者cube4d
相关产品推荐
相关产品推荐

