我有以下代码:

const getData = async function () {
  try {
    const response = await fetch(`${API_URL}/cars`, {
      signal: AbortSignal.timeout(5_000),
    });

    console.log(response);
  } catch (err) {
    console.log(err.name); //AbortError
    console.dir(err);
  }
};

getData();

在这里,getData使用fetch()从API端点检索数据,我将请求的signal属性设置为AbortSignal.timeout(5_000)以实现超时.

根据MDN文档,AbortSignal.timeout(TIME_IN_MS)将返回AbortSignal,它将在指定时间后自动中止.由于按下浏览器停止按钮、关闭标签(或一些其他内置的"停止"操作),信号以TimeoutError ON超时或AbortError中止.

我每次运行getData()时得到的响应是AbortError和消息The user aborted a request.,而不是TimeoutError,即使我将浏览器设置为减慢3G速度并将时间设置为getData()ms也是如此.我还try 在服务器中将响应时间设置为10秒,在前端将响应时间设置为无限制,并将超时设置为9000毫秒.

为什么我不能拿到TimeoutError分而只拿到AbortError分?

更新1:

这个问题似乎只适用于谷歌Chrome和Microsoft Edge等基于 chromium 的浏览器,但在Firefox中可以正常工作.

更新2:

正如@Kaiido所指出的,这似乎不仅是Chromium的错误,也是Safari的错误.问题在以下两种情况下都打开:

推荐答案

这确实是Chrome和Safari的一个漏洞.

我刚开了CRBUG 1431754,Safari有BUG 246069已经有很长一段时间了.

根据the specs

要使用promiserequestresponseObjecterror中止fetch()呼叫:

  1. error的成绩拒绝promise.

在这种情况下,您在fetch() method algorithm米的第11步打出了abort steps秒:

4.11用prequestresponseObjectrequestObject信号的中止原因中止fetch()呼叫.

这里"requestObject的信号的中止原因"是存储在我们的AbortSignal.reason中的对象,所以我们不仅应该有相同类型的DOMException,而且它甚至应该是相同的对象.

下面是另一个测试(进入步骤4.这一次,但结果是相同的),它确实再现了这个问题:

(async () => {
  const signal = AbortSignal.timeout(0);
  // Wait for the signal times out
  await new Promise((res) => setTimeout(res));
  const { reason } = signal;
  try {
   await fetch("./",{ signal });
  }
  catch(fetchErr) {
    console.log({
        reason: reason.name,      // Expected: "TimeoutError"
      fetchErr: fetchErr.name,  // Expected: "TimeoutError"
      same: fetchErr === reason // Expected: true
    });
  }
})();

不幸的是,我看不出你能做些什么.在fetch()个被拒绝的promise 中判断最初的AbortSignal#reason个可能会做到这一点,但这听起来有点老土,容易出现误报.

Javascript相关问答推荐

将下拉分区与工具提示结合起来

在JS中转换mysql UTC时间字段?

响应式JS DataTable中的Bootstrap 5弹出程序无法正常工作

Flutter:显示PDF和视频,但阻止下载

访客柜台的风格React.js

一次仅播放一个音频

vscode扩展-webView Panel按钮不起任何作用

Exceljs:我们在file.xlsx(...)&#中发现了一个问题'"" 39人;

有没有可能使滑动img动画以更快的速度连续?

如何将Map字符串,布尔值转换为{key:string;value:bo布尔值;}[]?<>

当点击注册页面上的注册按钮时,邮箱重复

空的结果抓取网站与Fetch和Cheerio

如何避免页面第一次加载时由于CSS样式通过JavaScript更改而出现闪烁

检索相加到点的子项

Reaction-SWR-无更新组件

如何防止ionic 输入中的特殊字符.?

如何在AG-Grid文本字段中创建占位符

为什么我看到的是回复,而不是我的文档?

AG-GRIDreact 显示布尔值而不是复选框

Angel Auth Guard-用户只有在未登录时才能访问登录页面,只有在登录时才能访问其他页面