fetch 还有隐藏技能?——原来它可以被取消!

AbortController API 能创建一个 signal,把它传给 fetch,就能随时中止一个或多个请求。 把它想象成——给你的网络请求配了个遥控器。

你大概已经用过无数次 fetch()

const response = await fetch("/api/data");

轻轻松松,对吧?

那如果——

  • 用户在请求未完成前跳转页面
  • 你发起了新请求,应该替换旧请求?
  • 取消一个长下载或不再需要的网络调用?

多年来,fetch() 没有“自带取消”。直到主角登场:AbortController

AbortController 到底是啥?

AbortController API 能创建一个 signal,把它传给 fetch,就能随时中止一个或多个请求。 把它想象成——给你的网络请求配了个遥控器

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

fetch("/api/data", { signal })
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => {
    if (err.name === "AbortError") {
      console.log("Request was cancelled!");
    } else {
      console.error(err);
    }
  });

// 需要时直接取消
controller.abort();

👩🏻💻 调用 controller.abort(),请求立刻停止。 👩🏻💻 fetch 会以 AbortError 结束,你可以优雅处理

为什么要取消 fetch

取消不是“锦上添花”,而是性能与体验必备。真实场景:

  • 搜索框:用户快速输入,不能每个键都发请求
  • 分页/筛选:新筛选发出,旧结果应作废
  • 导航:离开页面时,不要让请求继续跑 这些情况下,旧请求是浪费带宽,还可能引发竞态(旧结果覆盖新结果)。

图片

🛑 场景一:用户手动取消

<button id="cancel">Cancel</button>
<script>
const controller = new AbortController();
const signal = controller.signal;

fetch("https://jsonplaceholder.typicode.com/photos", { signal })
  .then(res => res.json())
  .then(data => console.log("Fetched:", data))
  .catch(err => {
    if (err.name === "AbortError") {
      console.log("Fetch aborted by user.");
    }
  });

document.getElementById("cancel").addEventListener("click", () => {
  controller.abort();
});
</script>

✌🏻 点“Cancel” → 请求立即终止✌🏻 catch 分支安全兜底

场景二:新的搜索自动取消旧请求(最常见)

let controller;

async function search(query) {
  if (controller) controller.abort(); // 取消旧请求
  controller = new AbortController();

  try {
    const res = await fetch(`/api/search?q=${query}`, {
      signal: controller.signal,
    });
    const data = await res.json();
    console.log("Results:", data);
  } catch (err) {
    if (err.name === "AbortError") {
      console.log("Old request aborted!");
    } else {
      console.error(err);
    }
  }
}

😎 每次新搜索都会自动终止上一次 😎 避免浪费与过期结果覆盖

📦 场景三:一把梭取消多个请求

const controller = new AbortController();

Promise.all([
  fetch("/api/user", { signal: controller.signal }),
  fetch("/api/posts", { signal: controller.signal }),
]).catch(err => {
  if (err.name === "AbortError") {
    console.log("All requests aborted.");
  }
});

// 一键全停
controller.abort();

适合仪表盘、批量加载等并发场景

Abort 之后会怎样?

  • 同一个 controller 一旦 abort()就不能复用;要新建:
controller.abort();
controller = new AbortController(); // 重新开始
  • fetch 会立刻以:
{ name: "AbortError", message: "The operation was aborted." }

    拒绝(reject)所以务必用 try/catch 或 catch() 正确处理。

    兼容性

    🥳 支持:Chrome 66+、Firefox 57+、Safari 12+、Edge 16+😬 不支持:IE(RIP 🪦)

    别再让 fetch 为所欲为

    AbortController 给了 fetch() 一直缺失的控制力。 无论是搜索、筛选还是各种用户交互,你都能即时取消无用请求——省时间、省流量、避竞态

    记住这句话:

    能跑 ≠ 该跑

    AI大模型学习福利

    作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

    一、全套AGI大模型学习路线

    AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

    因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取

    二、640套AI大模型报告合集

    这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

    因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

    三、AI大模型经典PDF籍

    随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。


    因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

    四、AI大模型商业化落地方案

    因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

    作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量

    评论
    成就一亿技术人!
    拼手气红包6.0元
    还能输入1000个字符
     
    红包 添加红包
    表情包 插入表情
     条评论被折叠 查看
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值