如何在JavaScript中使用AbortController中止一个获取请求

132 阅读2分钟

有时候,有必要中止一个获取请求。在这篇文章中,我们将探讨如何使用AbortController快速实现这一目标。

一个简单的获取请求

让我们从一个简单的获取请求开始。我们将抓取一些关于我的Github账户的元数据并记录到控制台。

fetch('https://api.github.com/users/nas5w')
  .then((res) => res.json())
  .then((data) => {
    console.log(data);
  });

如果我们检查我们的控制台,我们会看到一个描述我的账户的json对象已经被记录了。下面是这些数据的一个部分。

{"login":"nas5w","id":7538045,"node_id":"MDQ6VXNlcjc1MzgwNDU=","avatar_url":"https://avatars2.githubusercontent.com/u/7538045?v=4","gravatar_id":"","url":"https://api.github.com/users/nas5w","html_url":"https://github.com/nas5w"...}

使用AbortController

在同样的情况下,我们可以创建一个新的AbortController 对象的实例,并将fetch 的引用传递给AbortController 实例的signal 对象。

这就是我的意思。

const controller = new AbortController();
const signal = controller.signal;

fetch('https://api.github.com/users/nas5w', { signal })
  .then((res) => res.json())
  .then((data) => {
    console.log(data);
  });

所以现在,fetch 有一个对我们控制器实例的signal 对象的引用。我们可以通过调用控制器上的abort 来终止我们的获取。

const controller = new AbortController();
const signal = controller.signal;

fetch('https://api.github.com/users/nas5w', { signal })
  .then((res) => res.json())
  .then((data) => {
    console.log(data);
  });

controller.abort();

如果我们运行这个,我们不再记录返回的数据,因为我们已经立即中止了我们的fetch 请求!

处理取消

你可能已经注意到在我们的最后一个代码片段中,我们的fetch 请求并没有被优雅地中止,我们实际上在控制台中看到一个错误。

Uncaught (in promise) DOMException: The user aborted a request.

为了处理这个取消的错误,我们只需要catch 我们的错误。

const controller = new AbortController();
const signal = controller.signal;

fetch('https://api.github.com/users/nas5w', { signal })
  .then((res) => res.json())
  .then((data) => {
    console.log(data);
  })
  .catch((err) => {
    console.log(err);
  });

controller.abort();

现在如果我们运行我们的代码,我们看到我们优雅地记录了我们的错误。

DOMException: The user aborted a request.

所以,现在我们已经成功地中止了我们的获取请求,并抓住了相关的错误。

关于浏览器兼容性的说明

大多数现代浏览器都完全支持AbortController ,但(当然)如果你必须支持IE,你就不走运了请务必查看相关的MDN文档以获得完整的兼容性信息。