JavaScript 教程:使用 AbortController 中断 Fetch 请求

JavaScript 教程:使用 AbortController 中断 Fetch 请求

ru.javascript.info Современный учебник JavaScript ru.javascript.info 项目地址: https://gitcode.com/gh_mirrors/ru/ru.javascript.info

理解 Fetch 请求的中断需求

在现代 Web 开发中,fetch API 是发起网络请求的主要方式。但有时我们需要中断正在进行的请求,比如用户导航离开页面或取消了操作。由于 JavaScript 的 Promise 本身不支持取消操作,我们需要借助 AbortController 来实现这一功能。

AbortController 基础

AbortController 是一个专门设计用于中断异步操作的 JavaScript 内置对象。它的工作原理非常简单:

  1. 创建控制器

    const controller = new AbortController();
    
  2. 控制器结构

    • abort() 方法:调用时触发中断
    • signal 属性:用于监听中断事件
  3. 基本用法示例

    const controller = new AbortController();
    const signal = controller.signal;
    
    // 添加中断事件监听
    signal.addEventListener('abort', () => {
      console.log('请求已被中断');
    });
    
    // 触发中断
    controller.abort();
    console.log(signal.aborted); // 输出: true
    

结合 Fetch 使用 AbortController

AbortControllerfetch 结合使用非常简单:

  1. 创建控制器并传递 signal

    const controller = new AbortController();
    
    fetch('https://api.example.com/data', {
      signal: controller.signal
    });
    
  2. 中断请求

    controller.abort();
    
  3. 错误处理: 当请求被中断时,fetch 会抛出一个特殊的 AbortError,我们需要捕获并处理它:

    try {
      const response = await fetch(url, {
        signal: controller.signal
      });
    } catch (error) {
      if (error.name === 'AbortError') {
        console.log('请求被用户中断');
      } else {
        console.error('其他错误:', error);
      }
    }
    

实际应用场景

1. 超时中断

const controller = new AbortController();
// 设置1秒超时
const timeoutId = setTimeout(() => controller.abort(), 1000);

try {
  const response = await fetch('/api/data', {
    signal: controller.signal
  });
  clearTimeout(timeoutId);
  // 处理响应
} catch (error) {
  if (error.name === 'AbortError') {
    console.log('请求超时');
  }
}

2. 批量请求中断

AbortController 的强大之处在于可以同时中断多个请求:

const urls = [
  '/api/user',
  '/api/posts',
  '/api/comments'
];

const controller = new AbortController();

// 创建多个fetch请求
const requests = urls.map(url => 
  fetch(url, { signal: controller.signal })
);

// 统一中断所有请求
document.getElementById('cancel-button').addEventListener('click', () => {
  controller.abort();
});

try {
  const responses = await Promise.all(requests);
  // 处理所有响应
} catch (error) {
  if (error.name === 'AbortError') {
    console.log('所有请求已被中断');
  }
}

3. 与其他异步任务结合

AbortController 不仅适用于 fetch,还可以用于其他异步操作:

function longRunningTask(signal) {
  return new Promise((resolve, reject) => {
    const timer = setInterval(() => {
      if (signal.aborted) {
        clearInterval(timer);
        reject(new DOMException('Aborted', 'AbortError'));
      }
      // 执行任务...
    }, 100);
  });
}

const controller = new AbortController();

// 同时运行fetch和自定义任务
Promise.all([
  fetch('/api/data', { signal: controller.signal }),
  longRunningTask(controller.signal)
]).catch(error => {
  if (error.name === 'AbortError') {
    console.log('任务被中断');
  }
});

// 中断所有任务
controller.abort();

注意事项

  1. 浏览器兼容性:虽然现代浏览器都支持 AbortController,但在旧版浏览器中可能需要 polyfill。

  2. 内存管理:中断请求后,确保清理所有事件监听器以避免内存泄漏。

  3. 错误处理:始终处理 AbortError,避免它被当作未处理的 Promise 拒绝。

  4. 状态检查:在调用 abort() 前,可以检查 signal.aborted 属性了解当前状态。

总结

AbortController 为 JavaScript 提供了一种标准化的方式来中断异步操作,特别是网络请求。通过本文的学习,你应该已经掌握了:

  • 如何创建和使用 AbortController
  • 如何中断单个或多个 fetch 请求
  • 如何将中断机制与其他异步任务集成
  • 如何处理中断引发的错误

这种模式不仅使你的应用更加健壮,还能提升用户体验,特别是在需要处理长时间运行的操作或用户可能取消的任务时。

ru.javascript.info Современный учебник JavaScript ru.javascript.info 项目地址: https://gitcode.com/gh_mirrors/ru/ru.javascript.info

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颜钥杉Harriet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值