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

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;
}

关键修改点

  1. 点击事件改为async函数:只有在async函数内部才能使用await,确保请求完成后再执行后续代码。
  2. 异步函数直接返回结果:去掉全局变量,让函数返回请求得到的JSON或公里数,调用时通过await接收,避免旧数据干扰。
  3. 添加错误处理:用try/catch包裹异步操作,防止请求失败导致页面崩溃,同时给用户友好提示。
  4. 模板字符串优化URL:把拼接URL改成模板字符串,更易读。
  5. 公里数格式处理:把返回的米数转成公里并保留两位小数,显示更合理。

这样修改后,点击一次按钮就能按顺序完成所有请求,并正确更新DOM内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:45:06