对对,AbortController 是 fetch 用来取消请求的控制器,不是拦截器。
最基础用法:
1 2 3 4 5 6 7 8
| const controller = new AbortController()
fetch("/api/user", { signal: controller.signal, })
controller.abort()
|
比如 3 秒超时自动取消:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const controller = new AbortController()
const timer = setTimeout(() => { controller.abort() }, 3000)
try { const res = await fetch("/api/user", { signal: controller.signal, })
clearTimeout(timer)
const data = await res.json() console.log(data) } catch (err) { if (err.name === "AbortError") { console.log("请求被取消了") } else { console.error("请求失败", err) } }
|
封装成小工具:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| async function request(url, options = {}) { const { timeout = 5000, ...fetchOptions } = options
const controller = new AbortController()
const timer = setTimeout(() => { controller.abort() }, timeout)
try { const res = await fetch(url, { ...fetchOptions, signal: controller.signal, })
clearTimeout(timer)
if (!res.ok) { throw new Error(`HTTP ${res.status}`) }
return await res.json() } catch (err) { if (err.name === "AbortError") { throw new Error("请求超时或已取消") }
throw err } }
|
用法:
1 2 3
| const data = await request("/api/user", { timeout: 3000, })
|
手动取消也可以:
1 2 3 4 5 6 7 8
| const controller = new AbortController()
const promise = fetch("/api/search?q=abc", { signal: controller.signal, })
controller.abort()
|
在搜索框里很常见:用户连续输入时,取消上一次还没完成的请求,避免旧结果覆盖新结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| let controller = null
async function search(keyword) { if (controller) { controller.abort() }
controller = new AbortController()
try { const res = await fetch(`/api/search?q=${keyword}`, { signal: controller.signal, })
const data = await res.json() console.log(data) } catch (err) { if (err.name !== "AbortError") { console.error(err) } } }
|
小幽捏一下重点:
AbortController 主要管这几件事:
const controller = new AbortController()
controller.signal // 传给 fetch
controller.abort() // 取消 fetch
它不能“拦截”请求,但可以配合封装的 request 实现 超时取消、重复请求取消、组件卸载取消请求 这些效果。