如何按顺序处理乱序返回的Fetch请求响应?
解决搜索请求响应乱序问题(原生JS方案)
核心逻辑
给每个请求分配唯一ID,仅处理最新请求的响应;同时用AbortController取消未完成的旧请求,减少无效资源消耗。
代码修改步骤
1. 添加状态变量追踪请求
在代码开头新增全局/闭包级变量,用于记录最新请求ID和取消控制器:
let houseHoldSearchInput = document.getElementById("household-search-input"); // 追踪最新请求的唯一标识 let latestRequestId = 0; // 用于取消未完成请求的控制器 let currentAbortController = null; window.addEventListener("load", (_event) => { houseHoldSearchInput.addEventListener("keyup", keyupSearch, false); });
2. 更新搜索触发函数
修改keyupSearch,每次发起新请求前取消旧请求,生成新ID,仅当响应属于最新请求时更新UI:
async function keyupSearch(e){ let searchVal = e.target.value.trim().replace(" ", "+"); if (searchVal === "") { insertSearchOptions([]); return; } // 取消之前未完成的请求 currentAbortController?.abort(); // 创建新的控制器 currentAbortController = new AbortController(); // 生成当前请求的唯一ID const requestId = ++latestRequestId; try { const data = await getSearchResults(searchVal, currentAbortController.signal); // 仅当当前请求是最新的,才更新搜索结果 if (requestId === latestRequestId) { insertSearchOptions(data); } } catch (err) { // 忽略请求取消的错误 if (err.name !== "AbortError") { console.error(err); } } }
3. 适配请求函数支持取消
修改getSearchResults和get_household,接收AbortSignal并传递给fetch:
async function getSearchResults(searchVal, signal){ return get_household(searchVal, 1, 30, "first_name", "desc", signal); } export function get_household(search_value, page, page_size, sort_by, sort_order, signal) { return fetch(`${api_server}/api/household/?search_value=${search_value}&page=${page}&page_size=${page_size}&sort_by=${sort_by}&sort_order=${sort_order}`, { method: "GET", headers: { "Authorization": `Bearer ${jwt}`, }, signal: signal, // 绑定取消信号 }) .then(res => { if (!res.ok) throw new Error(`请求失败:${res.status}`); return res.json(); }) .then(data => { data.data.sort((a, b) => `${a.first_name} ${a.last_name}`.localeCompare(`${b.first_name} ${b.last_name}`)); return data.data; }) .catch(err => { // 仅打印非取消类错误 if (err.name !== "AbortError") { console.error(err); } throw err; }); }
方案优势
- 自动忽略过时请求的响应:用户快速输入时,只有最后一次输入对应的结果会更新UI,彻底解决乱序问题
- 减少无效请求:通过取消未完成的旧请求,降低后端负载和前端无用处理
- 不依赖防抖:输入过程中如果某请求快速返回,能及时更新结果,最后一次请求也会优先处理,兼顾响应速度和准确性
内容的提问来源于stack exchange,提问作者Pepe Alvarez
相关产品推荐
相关产品推荐

