请求队列怎么避免重复发送相同接口?

轩辕玉军 阅读 44

我在做搜索建议功能,用户输入时会频繁触发请求,现在用了一个简单的队列控制,但发现如果快速输入相同关键词还是会发多次请求。试过加防抖,但业务要求不能延迟显示结果,所以想用队列去重,但不知道怎么高效判断“相同请求”。

目前代码大概是这样:

const requestQueue = new Set();

const fetchSuggestions = async (query) => {
  if (requestQueue.has(query)) return;
  requestQueue.add(query);
  
  try {
    const res = await api.get(<code>/suggest?q=${query}</code>);
    return res.data;
  } finally {
    requestQueue.delete(query);
  }
};

但问题是 query 参数可能带时间戳或顺序不同(比如 q=react&lang=zh 和 lang=zh&q=react),这种算不算同一个请求?有没有更靠谱的去重方案?

我来解答 赞 13 收藏
二维码
手机扫码查看
1 条解答
司徒正毅
一般这样处理,可以对请求参数进行标准化,确保相同的查询参数无论顺序如何都生成相同的键。一种常见的做法是将参数对象转换为一个有序字符串或者 JSON 字符串。比如可以先对参数进行排序,然后再拼接成字符串。这样就能避免因为参数顺序不同而导致的重复请求。

你可以试试下面这个方法:

const requestQueue = new Set();

const normalizeQuery = (params) => {
const sortedKeys = Object.keys(params).sort();
return sortedKeys.map(key => ${key}=${encodeURIComponent(params[key])}).join('&');
};

const fetchSuggestions = async (queryParams) => {
const normalizedQuery = normalizeQuery(queryParams);
if (requestQueue.has(normalizedQuery)) return;
requestQueue.add(normalizedQuery);

try {
const res = await api.get(/suggest?${normalizedQuery});
return res.data;
} finally {
requestQueue.delete(normalizedQuery);
}
};


这样无论是 q=react&lang=zh 还是 lang=zh&q=react,都会被标准化为同一个字符串,从而避免重复请求。希望这个方法能帮到你。
点赞
2026-03-21 04:01