我有以下代码:
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();
Run Code Online (Sandbox Code Playgroud)
在这里,getData 用于fetch()从 API 端点检索数据,我将signalrequest 的属性设置为AbortSignal.timeout(5_000)以实现超时。
根据 MDN 文档,AbortSignal.timeout(TIME_IN_MS)将返回AbortSignal将在指定时间后自动中止。该信号会因TimeoutError超时或由于AbortError按下浏览器停止按钮、关闭选项卡(或某些其他内置“停止”操作)而中止。
我每次运行时得到的响应getData()都是AbortError消息The user aborted a request.,但从来没有TimeoutError,即使我将浏览器设置为减慢 3G 并将时间设置为 100 毫秒。我还尝试将服务器中的响应设置为 10 秒,前端设置为无限制,超时设置为 9000 毫秒。
为什么我没有得到TimeoutError而只是得到AbortError?
此问题似乎仅适用于基于 chromium 的浏览器,例如 Google Chrome、Microsoft Edge,但在 Firefox 中却按预期工作。
正如 @Kaiido 所指出的,这似乎不仅是 Chromium 的错误,也是 Safari 的错误。问题已在以下两个方面展开:
这确实是 Chrome 和 Safari 的 bug。
\n我刚刚打开CRBUG 1431754,Safari 已经有BUG 246069相当长一段时间了。
\n根据规格
\n\n\n要中止
\nfetch()带有promise、request、responseObject和error的调用:\n
\n- 拒绝有错误的承诺。
\n
在这种情况下,您将执行方法算法第 11 步中设置的中止步骤:fetch()
\n\n4.11
\nfetch()使用p、request、responseObject和requestObject \xe2\x80\x99s 信号\xe2\x80\x99s 中止原因中止调用。
这里“ requestObject \xe2\x80\x99s signal\xe2\x80\x99s abort Reason”是存储在 our 中的对象AbortSignal.reason,所以我们不仅应该有相同类型的DOMException,而且它甚至应该是相同的对象。
这是另一个重现该问题的测试(这次是执行步骤 4,但结果是相同的):
\n(async () => {\n const signal = AbortSignal.timeout(0);\n // Wait for the signal times out\n await new Promise((res) => setTimeout(res));\n const { reason } = signal;\n try {\n await fetch("./",{ signal });\n }\n catch(fetchErr) {\n console.log({\n reason: reason.name, // Expected: "TimeoutError"\n fetchErr: fetchErr.name, // Expected: "TimeoutError"\n same: fetchErr === reason // Expected: true\n });\n }\n})();Run Code Online (Sandbox Code Playgroud)\r\n不幸的是,我不知道你能对此做些什么......AbortSignal#reason在fetch()承诺拒绝时检查原始文件可能会做到这一点,但这听起来有点黑客并且容易出现误报。
| 归档时间: |
|
| 查看次数: |
2454 次 |
| 最近记录: |