關注分離(Separation of Concerns)在前端開發中的實踐演進:從 XMLHttpRequest 到 Fetch API
一、關注分離的核心價值
關注分離(SoC)是軟件工程領域的重要設計原則,強調將系統分解為不同維度的功能模塊,每個模塊只負責單一職責。這一思想在前端領域的演進歷程中,最典型的案例莫過于網絡請求方式的迭代:從 XMLHttpRequest 到 Fetch API 的演變,清晰地展現了 SoC 原則如何推動技術架構的優化。
二、XMLHttpRequest 時代的關注耦合
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 架構的三大問題:
- 生命周期耦合:readyState 管理貫穿整個請求周期
- 異常處理分散:狀態碼校驗、解析錯誤、網絡錯誤分散在不同位置
- 數據處理侵入:響應解析與業務邏輯深度耦合
三、Fetch API 的架構解耦
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 攔截器封裝
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 業務層抽象
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();}
}
五、設計原則的延伸思考
- 可測試性增強:分離網絡模塊后,可單獨 mock 請求進行單元測試
- 可維護性提升:修改響應解析邏輯不會影響請求發送過程
- 擴展性優化:通過中間件機制可靈活添加緩存、日志等功能
- 生態統一:基于 Promise 的設計天然支持 async/await 語法
六、總結
從 XHR 到 Fetch 的演進證明,優秀的架構設計應遵循以下原則:
- 網絡協議處理與業務邏輯分離
- 數據處理流程分層明確
- 異常處理路徑集中統一
- 擴展機制開放靈活
在現代前端開發中,無論是 React 的 Hooks 設計還是 Vue 的 Composition API,都延續了關注分離的設計哲學。開發者應深入理解這一原則,在構建復雜應用時設計出更清晰、更健壯的代碼架構。