要是实在不知道要干什么,那就喝两杯思路就来了!

导航菜单

浏览器那些普通开发者很少接触的原生宝藏API

一、AbortController API 完整讲解

1. 核心作用

AbortController 是浏览器原生通用中断控制器,用来主动取消异步操作,终止正在进行的任务、释放资源,避免无效请求、事件监听占用带宽与内存。

支持中断的场景:

  • fetch 网络请求(最常用)

  • DOM 事件监听

  • Web Audio、MediaRecorder、WebSocket

  • 自定义异步逻辑:定时器、Promise、循环任务

2. API 基础结构

整套API由两部分组成:

1. AbortController 控制器本体

  • .signal:只读属性,返回 AbortSignal 信号对象

  • .abort(reason?):触发中断,可传入取消原因

2. AbortSignal 信号载体

  • .aborted:布尔值,标记任务是否已取消

  • .onabort:中断触发回调

  • .reason:取消原因

  • 静态方法 AbortSignal.timeout(ms):自动超时中断

3. 实用代码示例

示例1:手动取消 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('请求已手动取消');
    } else {
      console.log('其他网络错误', err);
    }
  });

// 任意时机终止请求
controller.abort('用户主动取消');

示例2:超时自动中断

fetch('/api/list', {
  signal: AbortSignal.timeout(3000)
}).catch(err => {
  if (err.name === 'TimeoutError') {
    console.log('请求超时');
  }
});

示例3:批量取消 DOM 事件监听

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

function handleScroll() {
  console.log(window.scrollY);
}

window.addEventListener('scroll', handleScroll, { signal });
// 卸载时统一清除监听
controller.abort();

示例4:封装可中断延时 Promise

function delay(ms, signal) {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(resolve, ms);
    signal.addEventListener('abort', () => {
      clearTimeout(timer);
      reject(new Error('任务被中断'));
    });
  });
}

const ctrl = new AbortController();
delay(5000, ctrl.signal).catch(e => console.log(e.message));
ctrl.abort();

示例5:单信号批量取消多个接口

const controller = new AbortController();
const { signal } = controller;

Promise.all([
  fetch('/api/user', { signal }),
  fetch('/api/order', { signal })
]);

controller.abort();

4. 业务落地场景

  • 搜索防抖:新输入取消上一轮请求,防止旧数据覆盖

  • 路由跳转:销毁页面所有 pending 请求,节省网络

  • 文件上传/下载:用户点击取消立刻断开连接

  • 接口统一超时管控

  • Vue/React组件卸载:清除请求、监听,杜绝内存泄漏

5. 核心特性

  • 单次触发:abort 仅第一次生效,信号一旦中断永久不可恢复

  • 信号复用:一个signal绑定多个任务,一次abort全部终止

  • 原生标准,无第三方依赖,IE不兼容

  • 错误区分:手动取消=AbortError,超时=TimeoutError

6. API 诞生时间 & 普及情况

  • 兼容上线:Chrome66、Firefox57 2018年初支持;Safari12.1 2019年完善,距今近8年

  • 大规模普及节点:2021年Axios废弃CancelToken,全面适配AbortController

  • 主流框架React/Vue3、SWR、ReactQuery全部作为官方清理标准

7. 为什么很多开发者很晚才知道?完全不用觉得落伍

  • 早期有替代方案:Axios CancelToken、xhr.abort、手动loading标记

  • 入门教程极少讲解高级WebAPI,只覆盖基础fetch/Promise

  • 组件库/请求库内部封装底层,业务开发看不见原生代码

  • 简单展示页、静态页面没有复杂异步清理痛点,不会主动学习

二、普通CRUD开发者很少接触,但极度好用的原生宝藏API

第一类:通用业务向(所有项目都能用,90%人不会主动写)

1. ResizeObserver 元素尺寸观察器

监听DOM宽高变化,替代window.resize,适配弹窗、图表、自适应容器

const ro = new ResizeObserver(entries => {
  chart.resize(entries[0].contentRect);
});
ro.observe(document.querySelector('#chart-box'));

2. IntersectionObserver 交叉视口观察器

高性能懒加载、无限滚动、曝光埋点,不阻塞主线程

const io = new IntersectionObserver((list)=>{
  list.forEach(item=>{
    if(item.isIntersecting) loadImage(item.target);
  })
},{rootMargin:'200px 0'});
io.observe(document.querySelectorAll('[data-src]'));

3. structuredClone 浏览器原生深拷贝

支持Map/Set/Date/循环引用,无需lodash

const origin = {map:new Map(), time:new Date()};
const copy = structuredClone(origin);

4. navigator.sendBeacon 页面关闭稳定埋点

页面刷新/切标签不丢失上报日志,普通fetch会被强制中断

window.addEventListener('pagehide',()=>{
  const data = JSON.stringify({stay:Date.now()-startTime});
  navigator.sendBeacon('/api/log', data);
});

5. Page Vis4>5. Page Visibility 页面可见性监听

切标签暂停视频、停止轮询,节省流量性能

document.addEventListener('visibilitychange',()=>{
  if(document.hidden){
    video.pause();
    clearInterval(pollTimer);
  }else{
    video.play();
  }
})

6. requestIdleCallback 主线程空闲调度

低优先级任务(预加载、埋点)空闲时执行,不阻塞渲染

requestIdleCallback(()=>{
  preloadAssets();
  sendLog();
})

7. BroadcastChannel 同源多标签通信

多页面同步登录状态、购物车,无需localStorage轮询

const channel = new BroadcastChannel('app-login');
channel.postMessage({type:'logout'});
channel.onmessage = e=>{
  if(e.data.type==='logout') location.href='/login';
}

8. Web Locks API 跨标签资源锁

防止多标签并发重复刷新token、重复提交接口

navigator.locks.request('token-lock',async ()=>{
  await refreshToken();
})

9. View Transitions API 原生页面切换动画

零CSS实现SPA平滑过渡

document.startViewTransition(()=>{
  renderNewPage();
})

10. Popover HTML原生悬浮弹窗

自带外部点击关闭、层级管理,无需封装下拉气泡

<button popovertarget="tip">打开提示</button>
<div id="tip" popover>原生提示弹窗</div>

第二类:专业场景专属API(95%业务开发一辈子碰不到)

  • File System Access:浏览器读写本地真实文件,在线编辑器、在线表格专用

  • Web Speech API:文字朗读、麦克风语音识别

  • EyeDropper:网页原生取色器,设计工具使用

  • WebUSB/WebSerial/WebHID:对接打印机、单片机、扫码枪硬件

  • Performance API:精细化性能打点,前端性能专项优化

  • Intl 国际化套件:原生货币、日期、相对时间格式化

  • Clipboard高级API:复制图片、富文本到剪贴板

第三类:小众/实验硬件API(极少场景使用)

电池状态、手机震动、用户闲置检测、WebNFC、WebMIDI、WebXR、浏览器支付API、环境光传感器

三、学习优先级建议

  1. 必学通用款:AbortController、ResizeObserver、IntersectionObserver、sendBeacon、structuredClone、Page Visibility

  2. 中后台进阶:BroadcastChannel、Web Locks、requestIdleCallback、Performance、Intl

  3. 可视化/工具类:文件读写API、语音、高级剪贴板、View Transitions

  4. 硬件/AR/支付:仅做了解即可,日常业务几乎用不上

发表评论