如何恢复已中止的Fetch请求?解决中止后无法再次调用的问题
解决Fetch请求中止后无法重新发起的问题
问题出在你复用了同一个AbortController实例——一旦调用abort(),该实例的signal会永久处于中止状态,后续再用这个signal发起请求会直接触发错误。
解决方案:每次发起请求时创建新的AbortController实例
我们需要在每次点击startFetch时生成新的控制器,同时用变量追踪当前活跃的控制器,确保stopFetch能正确中止当前请求。
修改后的完整代码:
const startFetch = document.querySelector("#startFetch"); const stopFetch = document.querySelector("#stopFetch"); // 用于保存当前活跃的控制器实例 let currentController = null; const fetchTodos = async () => { // 每次发起请求前创建新的AbortController currentController = new AbortController(); try { const response = await fetch("https://jsonplaceholder.typicode.com/todos", { signal: currentController.signal }); const todos = await response.json(); console.log(todos); } catch (err) { // 忽略中止请求的错误,避免不必要的日志 if (err.name !== "AbortError") { console.log(err.message); } } finally { // 请求完成或中止后清空当前控制器 currentController = null; } }; startFetch.addEventListener("click", fetchTodos); stopFetch.addEventListener("click", () => { // 只有存在活跃控制器时才调用中止 if (currentController) { currentController.abort(); } });
<button id="startFetch">startFetch</button> <button id="stopFetch">stopFetch</button>
关键改动说明
- 移除了全局固定的
controller,改为在每次请求时创建新实例,确保每次请求的signal都是全新可用的 - 新增
currentController变量追踪当前活跃的请求控制器,让stopFetch能精准中止当前请求 - 使用
async/await重构代码,让错误处理更清晰,同时在finally块中清空控制器,避免内存泄漏 - 捕获错误时过滤
AbortError,减少无意义的日志输出
内容的提问来源于stack exchange,提问作者emirhan
相关产品推荐
相关产品推荐

