关注分离(Separation of Concerns)在前端开发中的实践演进:从 XMLHttpRequest 到 Fetch API

关注分离(Separation of Concerns)在前端开发中的实践演进:从 XMLHttpRequest 到 Fetch API

一、关注分离的核心价值

关注分离(SoC)是软件工程领域的重要设计原则,强调将系统分解为不同维度的功能模块,每个模块只负责单一职责。这一思想在前端领域的演进历程中,最典型的案例莫过于网络请求方式的迭代:从 XMLHttpRequest 到 Fetch API 的演变,清晰地展现了 SoC 原则如何推动技术架构的优化。

二、XMLHttpRequest 时代的关注耦合

js 复制代码
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');

xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      try {
        const data = JSON.parse(xhr.responseText);
        // 业务逻辑处理
      } catch (e) {
        console.error('解析失败', e);
      }
    } else {
      console.error('请求失败:', xhr.status);
    }
  }
};

xhr.onerror = function() {
  console.error('网络错误');
};

xhr.send();

这段经典代码暴露了 XHR 架构的三大问题:

  1. 生命周期耦合:readyState 管理贯穿整个请求周期
  2. 异常处理分散:状态码校验、解析错误、网络错误分散在不同位置
  3. 数据处理侵入:响应解析与业务逻辑深度耦合

三、Fetch API 的架构解耦

js 复制代码
fetch('/api/data')
  .then(response => {
    if (!response.ok) throw new Error(response.statusText);
    return response.json();
  })
  .then(data => {
    // 业务逻辑处理
  })
  .catch(error => {
    console.error('请求异常:', error);
  });

Fetch 通过分层设计实现了三个关键解耦:

3.1 协议层解耦
  • 使用 Promise 链式调用分离请求发起、响应接收、数据处理阶段
  • 每个 then 方法对应一个独立处理阶段
3.2 数据处理解耦
  • 通过 body mixin 提供多种解析方法(json(), text(), blob())
  • 业务层按需选择解析方式,不侵入网络层
3.3 错误处理统一
  • 网络故障自动触发 reject
  • HTTP 错误状态通过 response.ok 显式判断
  • 统一 catch 块处理所有异常场景

四、关注分离的进阶实践

4.1 拦截器封装
js 复制代码
const createFetchWithInterceptor = () => {
  const interceptors = [];
  
  return (url, options) => {
    let chain = Promise.resolve({ url, options });
    
    interceptors.forEach(({ request, response }) => {
      if (request) chain = chain.then(args => request(args));
      if (response) chain = chain.then(res => response(res));
    });
    
    return chain.then(args => fetch(args.url, args.options));
  };
};
4.2 业务层抽象
js 复制代码
class ApiClient {
  constructor(baseURL) {
    this.baseURL = baseURL;
  }

  async get(endpoint) {
    const response = await fetch(`${this.baseURL}${endpoint}`);
    return this._handleResponse(response);
  }

  async _handleResponse(response) {
    if (!response.ok) throw new ApiError(response.status);
    const contentType = response.headers.get('content-type');
    return contentType.includes('json') ? response.json() : response.text();
  }
}

五、设计原则的延伸思考

  1. 可测试性增强:分离网络模块后,可单独 mock 请求进行单元测试
  2. 可维护性提升:修改响应解析逻辑不会影响请求发送过程
  3. 扩展性优化:通过中间件机制可灵活添加缓存、日志等功能
  4. 生态统一:基于 Promise 的设计天然支持 async/await 语法

六、总结

从 XHR 到 Fetch 的演进证明,优秀的架构设计应遵循以下原则:

  • 网络协议处理与业务逻辑分离
  • 数据处理流程分层明确
  • 异常处理路径集中统一
  • 扩展机制开放灵活

在现代前端开发中,无论是 React 的 Hooks 设计还是 Vue 的 Composition API,都延续了关注分离的设计哲学。开发者应深入理解这一原则,在构建复杂应用时设计出更清晰、更健壮的代码架构。

相关推荐
Rousson20 分钟前
硬件学习笔记--65 MCU的RAM及FLash简介
开发语言·前端·javascript
萌萌哒草头将军25 分钟前
🏖️ TanStack Router:搜索参数即状态!🚀🚀🚀
javascript·vue.js·react.js
小疯仔2 小时前
使用el-input数字校验,输入汉字之后校验取消不掉
android·开发语言·javascript
wangbing11252 小时前
开发指南120-表格(el-table)斑马纹
javascript·vue.js·elementui
Joe5562 小时前
antDesignVue中a-upload上传组件的使用
前端·javascript
WKK_2 小时前
el-select 实现分页加载,切换也数滚回到顶部,自定义高度
前端·javascript·vue.js·elementui
保持学习ing2 小时前
帝可得 - 策略管理
java·javascript·vue.js·elementui·若依框架
咔咔库奇2 小时前
开发者体验提升:打造高效愉悦的开发环境
前端·javascript·vue.js·react.js·前端框架
午后书香3 小时前
egg.js基础入门,前端迈向全栈开发的第一步
javascript·node.js·egg.js
3Katrina3 小时前
为什么现代前端拒绝原生编程?组件化与框架的降维打击
前端·javascript·css