Node.js:给 fetch 加个超时,别让小脚本一直挂着

24 次浏览1 条回复

调接口的小脚本最怕网络一直不回,进程就像卡住了一样。Node.js 18.17+ 可以直接用 AbortSignal.timeout(),不用再手写 setTimeout。

// fetch-timeout.mjs
try {
  const res = await fetch('https://example.com', {
    signal: AbortSignal.timeout(3000)
  })

  if (!res.ok) throw new Error(`HTTP ${res.status}`)
  console.log((await res.text()).slice(0, 80))
} catch (err) {
  if (err.name === 'TimeoutError') {
    console.error('请求超时')
  } else {
    console.error('请求失败:', err.message)
  }
}

运行:node fetch-timeout.mjs。

超时只是兜底,正式代码里还得按接口特点决定是否重试;写重试时最好把总耗时也设上限,不然每次重试三秒,整体还是可能拖很久。

这个写法挺适合一次性脚本。补个小坑:如果外层还有自己的 AbortController,可以用 AbortSignal.any([controller.signal, AbortSignal.timeout(3000)]) 把手动取消和超时合在一起,Node 20+ 里比较顺手。