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

如何按顺序处理乱序返回的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 04:30:04