ajax请求中loading动画应在请求发起前显示、响应处理后关闭,核心是通过fetch的finally、xmlhttprequest的onloadend或封装函数确保无论成功失败都隐藏动画。

在发送 Ajax 请求前显示 Loading 动画、请求完成后关闭,核心是控制动画元素的显隐状态,关键在于把显示/隐藏逻辑放在请求发起前和响应处理(无论成功或失败)之后。
1. 使用原生 fetch + 手动控制 Loading
最直接的方式:在调用 fetch 前显示 Loading,然后在 then 和 catch 中统一关闭。
- 先通过 DOM 操作让 Loading 元素可见(例如添加 class 或设置 display)
- fetch 返回 Promise,务必在 .finally() 中关闭 Loading——它确保无论成功失败都会执行
- 避免只在 .then() 里关,否则报错时 Loading 会一直挂着
示例:
const loading = document.getElementById('loading');
const btn = document.getElementById('submitBtn');
btn.addEventListener('click', async () => {
loading.style.display = 'block'; // 显示 Loading
try {
const res = await fetch('/api/data');
const data = await res.json();
console.log(data);
} catch (err) {
console.error('请求失败:', err);
} finally {
loading.style.display = 'none'; // 一定关闭
}
});
2. 使用 XMLHttpRequest 时的对应时机
XMLHttpRequest 的生命周期更明确:在 .open() 后、.send() 前显示 Loading;在 onload 和 onerror 里都需关闭,也可统一写在 onloadend(兼容性较好,现代浏览器均支持)。
- onloadend 在请求完成时触发(包括 success/error/abort/timeouts),是比 onload+onerror 更简洁的选择
- 注意:不要在 onreadystatechange 中判断 readyState === 4 就关,因为 error 状态下也可能触发,但未必进 onload
示例:
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.onloadend = () => {
loading.style.display = 'none';
};
xhr.onerror = () => {
console.error('网络错误');
};
loading.style.display = 'block';
xhr.send();
3. 封装成可复用的请求函数(推荐)
把 Loading 控制逻辑抽离,避免每个请求重复写。可以传入 Loading 元素或回调函数,提升复用性。
- 接收一个 showLoading 和 hideLoading 函数,或直接传 DOM 元素
- 内部自动处理 finally / onloadend / catch,保证不遗漏
- 支持 Promise 链式调用,业务代码更干净
简易封装示例:
function request(url, options = {}) {
const { showLoading = () => {}, hideLoading = () => {} } = options;
showLoading();
return fetch(url, options)
.finally(() => hideLoading());
}
// 使用
request('/api/data')
.then(res => res.json())
.then(data => console.log(data));
4. 注意事项与常见坑
- DOM 元素必须存在且可访问,建议在元素挂载后再绑定事件,或用 document.addEventListener('DOMContentLoaded', ...)
- 如果 Loading 是全屏遮罩,记得加 pointer-events: none 或禁用按钮,防止用户重复点击
- 多个并发请求时,简单地 show/hide 可能导致“刚关又开”,可用计数器或 Promise 队列管理(进阶需求)
- Vue/React 等框架中,优先用响应式数据控制 v-show / {loading &&
},而非直接操作 style
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











