如何在用户快速切换搜索时取消上一个未完成的请求?

琪航 Dev 阅读 3

我做了一个搜索框,每次输入就发请求去后端查数据。但用户打字快的时候,前面的请求还没回来,新的又发出去了,结果旧数据覆盖了新数据,显示错乱。我试过用 AbortController,但不知道怎么在 React 里正确清理和复用它。

这是我的简化代码:

useEffect(() => {
  const controller = new AbortController();
  if (searchTerm) {
    fetch(<code>/api/search?q=${searchTerm}</code>, { signal: controller.signal })
      .then(res => res.json())
      .then(data => setResult(data));
  }
  return () => controller.abort();
}, [searchTerm]);

但有时候还是会报 “AbortError”,而且偶尔新结果被旧的覆盖,是不是哪里没处理对?

我来解答 赞 0 收藏
二维码
手机扫码查看
1 条解答
Newb.司卿
我之前踩过这个坑,确实挺头疼的。你遇到的“AbortError”是正常的,因为你正在取消之前的请求。至于新结果被旧的结果覆盖,问题可能出在请求完成后的处理逻辑上。

你可以在发起请求前检查是否有正在进行的请求,并且在请求完成后检查当前的 search term 是否与发起请求时的一致。如果不是,就忽略这次请求的结果。

看下这个改过的代码:

pre class="pure-highlightjs line-numbers">useEffect(() => {
let currentSearchTerm = searchTerm;
const controller = new AbortController();

if (searchTerm) {
fetch(/api/search?q=${searchTerm}, { signal: controller.signal })
.then(res => res.json())
.then(data => {
// 检查当前的 search term 是否与发起请求时的一致
if (currentSearchTerm === searchTerm) {
setResult(data);
}
})
.catch(err => {
// 忽略被取消的请求
if (err.name !== 'AbortError') {
console.error('Fetch error:', err);
}
});
}

return () => {
controller.abort();
};
}, [searchTerm]);


这样处理后,只有当请求完成时当前的 search term 没有变化,才会更新结果,否则就忽略掉这个结果。希望这能解决你的问题。
点赞
2026-03-20 18:04