JavaScript 进行 异步请求 的方式经历了多个阶段的发展,每个阶段都在解决上一阶段的问题,变得 更简洁、易用、强大 。我们从 历史发展角度 来看,主要经历了以下几个阶段:
1️⃣ 早期阶段:XHR(XMLHttpRequest)
📌 诞生背景
- 1999 年 W3C 引入
XMLHttpRequest
,是 AJAX(异步 JavaScript 和 XML) 的基础。 - 主要用于 局部刷新页面,避免整个页面重新加载,提高用户体验。
- 早期用于 XML 交互 ,后来也支持 JSON。
🚀 示例代码
javascript
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data", true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log("响应数据:", xhr.responseText);
}
};
xhr.send();
⚠️ 存在问题
❌ 回调地狱(Callback Hell)
❌ 代码 复杂冗长
❌ 不支持 Promise,难以链式调用
❌ 手动解析 JSON,容易出错
🔹 改进方向 :封装 XHR (jQuery AJAX)
2️⃣ jQuery.ajax()(2006 年)
📌 诞生背景
- jQuery 诞生 (2006 年),封装了
XMLHttpRequest
,让 AJAX 更简单。 - 降低 XHR 复杂度 ,支持 链式调用 和 JSON 自动解析。
- 曾经是 最流行的前端 AJAX 方式 ,但后来逐渐被
fetch
取代。
🚀 示例代码
javascript
$.ajax({
url: "https://api.example.com/data",
method: "GET",
dataType: "json",
success: function (data) {
console.log("数据:", data);
},
error: function (err) {
console.error("请求失败:", err);
}
});
⚠️ 存在问题
❌ 仍然基于回调,不能优雅地处理异步流程
❌ 依赖 jQuery,影响性能
❌ 不符合现代 JavaScript 原生标准
🔹 改进方向 :Promise 取代回调地狱 (Fetch API)
3️⃣ Fetch API(2015 年,ES6+)
📌 诞生背景
- ES6 及 ES7 提出了 Promise ,解决了 回调地狱 问题。
- Fetch API 诞生于 2015 年 ,是现代浏览器 原生支持 的异步请求方式。
- 基于 Promise,支持链式调用,语法更加简洁。
🚀 示例代码
javascript
fetch("https://api.example.com/data")
.then(response => response.json()) // 解析 JSON
.then(data => console.log("数据:", data))
.catch(error => console.error("请求失败:", error));
✅ 优势
✅ 原生支持,无需第三方库
✅ 基于 Promise,语法简洁
✅ 支持多种数据格式(JSON、Blob、FormData)
⚠️ 存在问题
❌ 不支持超时控制 (需要 AbortController
)
❌ 错误不会抛异常(需要 catch
处理)
❌ 不自动发送 Cookies(需要 credentials: "include"
)
🔹 改进方向 :async/await
让代码更直观 (Async/Await)
4️⃣ Async/Await(2017 年,ES8+)
📌 诞生背景
- 2017 年 ES8 推出了 async/await ,让异步代码写起来更像 同步代码。
- 让
fetch
更易读 ,消除了 Promise 链式调用的复杂性。
🚀 示例代码
javascript
async function fetchData() {
try {
let response = await fetch("https://api.example.com/data");
let data = await response.json();
console.log("数据:", data);
} catch (error) {
console.error("请求失败:", error);
}
}
fetchData();
✅ 优势
✅ 代码简洁,像写同步代码一样
✅ 更易读,避免 then()
链式嵌套
✅ 更容易处理错误(用 try/catch
)
⚠️ 存在问题
❌ 默认不支持超时控制,需要 AbortController
❌ 顺序执行多个请求时,可能会阻塞(需 Promise.all()
)
🔹 改进方向 :提供更高级的功能 (Axios)
5️⃣ Axios(第三方库,2016 年发布)
📌 诞生背景
fetch
没有提供超时控制、自动 JSON 解析等功能,开发者需要自己封装。- Axios 在 2016 年 发布,成为 最受欢迎的异步请求库 ,比
fetch
更强大。 - 基于 Promise ,但提供了 更多功能(请求取消、超时、拦截器等)。
🚀 示例代码
javascript
axios.get("https://api.example.com/data")
.then(response => console.log("数据:", response.data))
.catch(error => console.error("请求失败:", error));
🚀 使用 async/await
javascript
async function fetchData() {
try {
let response = await axios.get("https://api.example.com/data");
console.log("数据:", response.data);
} catch (error) {
console.error("请求失败:", error);
}
}
fetchData();
✅ 优势
✅ 自动解析 JSON,不用手动 response.json()
✅ 支持超时控制(timeout
选项)
✅ 支持请求和响应拦截器
✅ 自动发送 Cookies(withCredentials: true
)
✅ 支持请求取消(CancelToken
)
⚠️ 存在问题
❌ 需要额外安装(不是浏览器内置)
🔚 总结:从 XHR 到 Axios
方式 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
XHR (1999) | 早期异步请求基础 | 代码复杂、回调地狱 | 过时,不推荐使用 |
jQuery.ajax() (2006) | 更简洁的 XHR 封装 | 依赖 jQuery,回调地狱 | 适用于老旧项目 |
Fetch API (2015) | 原生支持,基于 Promise | 需手动处理超时、错误 | 适用于现代前端开发 |
Async/Await (2017) | 代码更直观、同步化 | 仍然需 fetch 配合 |
适用于大多数异步操作 |
Axios (2016) | 自动解析 JSON、超时控制、拦截器 | 需额外安装 | 适用于企业级项目 |
📌 最佳实践
1️⃣ 如果是简单的前端请求 → 用 fetch + async/await
2️⃣ 如果需要超时控制、自动解析 JSON → 用 Axios
3️⃣ 如果是老项目 → jQuery.ajax()
(但建议升级)
4️⃣ 不要再用 XHR(太古老了)
🚀 现代前端开发推荐 fetch
或 Axios
!