含两个await的异步函数执行完请求后无法暂停再跳转问题排查
问题根因
- 错误引入了仅适配Node.js环境的
node-fetch库,和浏览器原生的async/await机制存在兼容性问题,导致await无法正常等待fetch请求执行完成。 - fetch请求的错误处理逻辑存在缺陷:fetch仅在网络异常时才会触发reject,返回HTTP 4xx/5xx状态码时不会自动抛错,原有代码没有对这部分场景做判断。
- 两个封装的请求函数内部捕获错误后没有向外抛出,外层无法感知请求的实际执行结果;同时fetch的catch块直接复用了axios的错误处理逻辑,访问不存在的
err.response属性会触发二次报错。 - 外层submit的异步回调没有添加统一的异常捕获逻辑,一旦出现未处理的Promise异常,代码执行顺序会出现混乱。
修复方案
1. 修改封装的请求函数
// 移除node-fetch引入,直接使用浏览器原生fetch import axios from "axios"; export const updateEvento = async function(data, type) { try { const url = "/api/v1/eticket/visitor"; const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); // 新增HTTP状态码校验 if (!response.ok) throw new Error('Evento接口请求异常'); const res = await response.json(); if (res.status === "success") { console.log(`${type.toUpperCase()} Updated`); return true; } // 业务逻辑失败也抛出错误 throw new Error(res.message || 'Evento数据更新失败'); } catch (err) { // 适配fetch的错误结构 alert(err.message); // 向外抛出错误,让外层可以感知请求结果 throw err; } }; export const updateSettings = async function(data, type) { try { const url = type === "password" ? "/api/v1/users/updateMyPassword" : "/api/v1/users/updateMe"; const res = await axios({ method: "PATCH", url, data, }); if (res.data.status === "success") { console.log(`${type.toUpperCase()} Updated`); return true; } throw new Error(res.data.message || '用户数据更新失败'); } catch (err) { alert(err.response?.data?.message || err.message); throw err; } };
2. 修改submit事件回调
const saveSettings = document.querySelector(".form-user-data"); if (saveSettings) { saveSettings.addEventListener("submit", async (e) => { e.preventDefault(); // 外层添加统一异常捕获 try { const firstName = document.getElementById("firstName").value; const lastName = document.getElementById("lastName").value; const mobile = document.getElementById("mobile").value; const email = document.getElementById("email").value; const company = document.getElementById("company").value; const profile = document.getElementById("profile").value; const country = document.getElementById("country").value; const nationality = document.getElementById("nationality").value; const type = document.getElementById("type").value; const visitorId = document.getElementById("visitorId").value; const visitorForEvento = { VisitorNumber: visitorId, FirstName: firstName, LastName: lastName, Mobile: mobile, Email: email, Company: company, JobTitle: profile, Country: country, Nationality: nationality, Category: type, }; // 等待两个请求依次执行完成 await updateEvento(visitorForEvento, "evento"); await updateSettings( { firstName, lastName, mobile, email, company, profile, country, nationality, type, }, "data" ); // 到此处两个请求必然全部成功,可添加暂停逻辑后跳转 alert("数据更新完成,即将跳转"); // 示例:暂停1秒后跳转 setTimeout(() => { window.location.href = '你的目标跳转地址'; }, 1000); } catch (err) { // 任意请求失败都会进入此处,不会执行跳转逻辑 console.error('操作失败:', err); } }); }
内容的提问来源于stack exchange,提问作者Alim Bolar
相关产品推荐
相关产品推荐

