如何使 fetch() 请求超时

在开发使用网络的应用程序时,要记住的第一条规则是不要依赖网络

网络不可靠,因为 HTTP 请求或响应可能由于多种原因而失败:

  • 用户离线
  • DNS 查询失败
  • 服务器没有响应
  • 服务器响应但出现错误
  • 和更多。

用户可以等待最多 8 秒来完成简单的请求。这就是为什么您需要对网络请求设置超时并在 8 秒后通知用户网络问题。

我将向您展示如何使用setTimeout()、中止控制器和fetch()API 来发出具有可配置超时时间的请求(包括有趣的演示!)。

1. 默认 fetch() 超时

默认情况下,fetch()请求在浏览器指示的时间超时。在 Chrome 中,网络请求超时为 300 秒,而在 Firefox 中为 90 秒。

 
 
async function loadGames() {
const response = await fetch('/games');
// fetch() timeouts at 300 seconds in Chrome
const games = await response.json();
return games;
}

300 秒甚至 90 秒远远超过用户期望完成一个简单的网络请求。

演示中,/gamesURL 被配置为在 301 秒内响应。单击加载游戏按钮开始请求,它将在 300 秒时超时(在 Chrome 中)。

2. fetch() 请求超时

fetch()API 本身不允许以编程方式取消请求。要在所需时间停止请求,您还需要一个中止控制器

以下是创建具有可配置超时的请求fetchWithTimeout()的改进版本:fetch()

 
 
async function fetchWithTimeout(resource, options = {}) {
const { timeout = 8000 } = options;
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
const response = await fetch(resource, {
...options,
signal: controller.signal
});
clearTimeout(id);
return response;
}

首先,const { timeout = 8000 } = options从对象中提取超时参数(以毫秒为options单位)(默认为 8 秒)。

const controller = new AbortController()创建一个中止控制器的实例。该控制器允许您随意停止fetch()请求。请注意,对于每个请求,必须创建一个新的中止控制,换句话说,控制器不可重用。

const id = setTimeout(() => controller.abort(), timeout)启动计时功能。一段timeout时间后,如果计时功能未被清除,controller.abort()将中止(或取消)获取请求。

下一行await fetch(resource, { ...option, signal: controller.signal })正确启动获取请求。controller.signal注意分配给signal属性的特殊值:它fetch()与中止控制器连接。

最后,clearTimeout(id)如果请求完成的速度快于时间,则清除中止计时功能timeout

现在这里是如何使用fetchWithTimeout()

 
 
async function loadGames() {
try {
const response = await fetchWithTimeout('/games', {
timeout: 6000
});
const games = await response.json();
return games;
} catch (error) {
// Timeouts if the request takes
// longer than 6 seconds
console.log(error.name === 'AbortError');
}
}

fetchWithTimeout()(而不是 simple fetch())启动一个在时间取消的请求timeout- 6 秒。

如果请求/games在 6 秒内未完成,则取消请求并引发超时错误。

您可以使用块error.name === 'AbortError'内的表达式catch来确定是否存在请求超时。

打开演示并单击加载游戏按钮。请求/games超时,因为它需要超过 6 秒。

三、总结

默认情况下,fetch()请求在浏览器设置的时间超时。例如,在 Chrome 中,此设置等于 300 秒。这比用户期望完成一个简单的网络请求要长得多。

发出网络请求时的一个好方法是将请求超时配置为大约 8 - 10 秒。

如帖子所示,使用setTimeout()和中止控制器,您可以创建fetch()配置为在您愿意时超时的请求。

检查中止控制器的浏览器支持,因为截至 2020 年它是一项实验性技术。它还有一个polyfill

请注意,如果不使用中止控制器,您将无法停止fetch()请求。不要使用这样的解决方案

您还知道哪些有关网络请求的其他良好做法?

喜欢帖子吗?请分享!

要在 JavaScript 中添加 Fetch 请求超时,可以使用 `AbortController` 和 `setTimeout` 函数的组合。 首先,创建一个 `AbortController` 对象,并通过它创建一个 signal。将该 signal 作为 Fetch 请求的参数传递给 `fetch` 函数。然后,使用 `setTimeout` 函数,设置一个超时时间,在超时时间到达时,调用 `AbortController` 对象的 `abort` 方法取消请求。 以下是一个示例代码: ```javascript const controller = new AbortController(); const signal = controller.signal; const fetchPromise = fetch('https://some-api.com/data', { signal }); const timeoutId = setTimeout(() => { controller.abort(); }, 5000); // 设置 5 秒超时时间 fetchPromise .then(response => response.json()) .then(data => { clearTimeout(timeoutId); // 处理返回的数据 }) .catch(error => { clearTimeout(timeoutId); if (error.name === 'AbortError') { console.log('请求超时!'); } else { console.error('请求失败!', error); } }); ``` 在这个示例中,我们使用 `AbortController` 和 `signal` 来创建 Fetch 请求。然后,我们设置了一个 5 秒的超时时间,并将其作为 `setTimeout` 函数的第二个参数传递。在 `fetchPromise` 被解决或拒绝时,我们使用 `clearTimeout` 函数取消超时定时器。 如果超时时间到达,超时定时器将调用 `AbortController` 对象的 `abort` 方法取消请求。在 `catch` 块中,我们检查错误类型,如果是 `AbortError`,则表示请求已经被取消,否则则表示请求失败。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值