获取 API 请求超时?

2022-08-30 01:23:29

我有一个请求:fetch-apiPOST

fetch(url, {
  method: 'POST',
  body: formData,
  credentials: 'include'
})

我想知道此情况的默认超时是什么?我们如何将其设置为特定值,如3秒或无限期秒?


答案 1

使用承诺竞赛解决方案将使请求挂起,并且仍在后台消耗带宽,并降低在处理过程中发出的最大允许并发请求数。

相反,请使用中止控制器来实际中止请求,下面是一个示例

const controller = new AbortController()

// 5 second timeout:
const timeoutId = setTimeout(() => controller.abort(), 5000)

fetch(url, { signal: controller.signal }).then(response => {
  // completed request before timeout fired

  // If you only wanted to timeout the request, not the response, add:
  // clearTimeout(timeoutId)
})

或者,您可以使用新添加的 AbortSignal.timeout(5000)...但它现在在大多数浏览器中都没有很好地实现。


AbortController也可以用于其他事情,不仅获取,还用于可读/可写流。更多较新的函数(特别基于承诺的函数)将越来越多地使用它。NodeJS也在其流/文件系统中实现了AbortController。我知道网络蓝牙也在研究它。现在,它也可以与addEventListener选项一起使用,并在信号结束时停止收听。


答案 2

更新,因为我的原始答案有点过时,我建议使用中止控制器,就像这里实现的那样:https://stackoverflow.com/a/57888548/1059828 或看看这个非常好的帖子,解释中止控制器与fetch:我如何取消HTTP fetch()请求?

过时的原始答案:

我真的很喜欢使用Promise.race的这个要点的干净方法

fetch WithoutthTimeout.js

export default function (url, options, timeout = 7000) {
    return Promise.race([
        fetch(url, options),
        new Promise((_, reject) =>
            setTimeout(() => reject(new Error('timeout')), timeout)
        )
    ]);
}

主要.js

import fetch from './fetchWithTimeout'

// call as usual or with timeout as 3rd argument

fetch('http://google.com', options, 5000) // throw after max 5 seconds timeout error
.then((result) => {
    // handle result
})
.catch((e) => {
    // handle errors and timeout error
})