【问题标题】:fetch() cancels with an AbortSignal, does res.json() too?fetch() 用 AbortSignal 取消,res.json() 也一样吗?
【发布时间】:2023-03-29 20:30:01
【问题描述】:

我了解使用 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 抛出的。

【问题讨论】:

    标签: javascript exception async-await fetch-api


    【解决方案1】:

    是的,这是官方行为。 json()(和朋友)消耗响应的正文。根据https://fetch.spec.whatwg.org/#dom-global-fetch 的第 10 步,该主体可能会因信号而处于中止状态。在这种情况下,json()(和朋友)基本上会重新抛出。

    【讨论】:

    • 正是我要找的,虽然硬规范有点难读,但我相信这就是我想要的,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 2020-01-31
    • 2018-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多