Node.js:给 fetch 加超时可以直接用 `AbortSignal.timeout`

15 次浏览3 条回复

写小脚本请求接口时,只想简单限制一下等待时间,不一定要自己手搓 AbortControllersetTimeout

环境:Node.js 18+,保存成 fetch-timeout-demo.mjs

const url = 'https://example.com'

try {
  const res = await fetch(url, {
    signal: AbortSignal.timeout(1000),
  })

  console.log(res.status)
  console.log((await res.text()).slice(0, 40))
} catch (err) {
  if (err.name === 'TimeoutError') {
    console.log('请求超时了')
  } else {
    throw err
  }
}

跑:

node fetch-timeout-demo.mjs

这个适合本地工具、一次性脚本这种轻场景。要是项目里已经有统一的 HTTP client,还是放到那层一起处理超时、重试和日志更顺。

这个点挺实用的。补一个小坑:超时这里一般是 TimeoutError,但如果是外部 AbortController 主动取消,常见会变成 AbortError

所以封一层工具函数时,最好别只按一种错误名判断,不然日志里容易把“用户取消”和“请求真超时”混在一起。

还有个细节:如果外面有重试循环,AbortSignal.timeout(1000) 最好每次请求重新建一个。

同一个 signal 超时后状态就固定了,拿去复用会导致后面的 fetch 直接被取消,看起来像接口一直秒失败。

这招配 fetch 还挺干净。

如果是库代码,我会顺手把超时时间当参数传进去,默认值别写死太短。像本地脚本 1s 可以,放到 CI 或网络慢一点的环境里,太容易误伤正常请求。