fetch() 用 AbortSignal 取消,res.json() 也一样吗?
Posted
技术标签:
【中文标题】fetch() 用 AbortSignal 取消,res.json() 也一样吗?【英文标题】:fetch() cancels with an AbortSignal, does res.json() too? 【发布时间】:2022-01-12 13:55:27 【问题描述】:我了解使用 AbortSignal 取消正在进行的请求的工作流程,即将其传递给选项:
const res = await fetch('/endpoint', signal );
const data = await res.json();
但是,如果信号在请求本身完成之后被取消,但在数据被解析之前会发生什么?像这样:
const res = await fetch('/endpoint', signal );
// Cancel signal here
const data = await res.json();
My tests 在 Firefox、Chrome 和 Safari 中显示会在res.json()
期间正确取消并抛出,但这是官方行为吗?
const log = (...text) => document.body.insertAdjacenthtml('beforeend', `$text.join(' ')<br />`);
(async () =>
try
const controller = new AbortController();
const signal = controller.signal;
const res = await fetch('https://swapi.dev/api/films/2/', signal );
log('Request:', signal.aborted);
controller.abort();
log('Before:', signal.aborted);
const data = await res.json();
log('After:', signal.aborted);
catch (error)
log('Cancelled:', error.name);
)();
// Request: false
// Before: true
// Cancelled: AbortError
从输出中我们可以看到它正确地在res.json()
上抛出,它永远不会到达After
步骤,它是用AbortError
抛出的。
【问题讨论】:
【参考方案1】:是的,这是官方行为。 json()
(和朋友)消耗响应的正文。根据https://fetch.spec.whatwg.org/#dom-global-fetch 的第 10 步,该主体可能会因信号而处于中止状态。在这种情况下,json()
(和朋友)基本上会重新抛出。
【讨论】:
正是我要找的,虽然硬规范有点难读,但我相信这就是我想要的,谢谢!以上是关于fetch() 用 AbortSignal 取消,res.json() 也一样吗?的主要内容,如果未能解决你的问题,请参考以下文章
前端进阶使用fetch/axios时, 如何取消http请求
取消设置 mysql_fetch_field 对象值 MYSQL PHP
使用 Fetch api Javascript 取消订阅电子邮件