本文详解 jquery 中异步 ajax 请求的响应处理机制,重点解决因未正确处理异步时序导致的“取不到 json 数据”问题,并提供可立即运行的修复方案与最佳实践。
本文详解 jquery 中异步 ajax 请求的响应处理机制,重点解决因未正确处理异步时序导致的“取不到 json 数据”问题,并提供可立即运行的修复方案与最佳实践。
在 jQuery 中使用 $.ajax() 发起请求时,请求本质上是异步的——这意味着后续代码不会等待服务器响应返回后再执行。你原始代码中的核心问题正在于此:
$('#btPay').bind('click', function() {
myFunction(); // 立即触发 AJAX,但不阻塞执行
setResponse(); // 立即执行!此时 response 还未返回 → resJson 仍为 undefined
});
myFunction() 内部调用 $.ajax().done(...) 是注册一个回调函数,它仅在响应成功到达后才被调用;而 setResponse() 却在 AJAX 尚未完成时就被调用,因此必然无法读取到有效数据。
✅ 正确做法:将数据消费逻辑置于回调内部
无需全局变量、无需 async/await(除非你改用 Promise 链或 await $.ajax()),最简洁可靠的方案是直接在 .done() 回调中处理响应并更新 DOM:
$('#btPay').on('click', function(e) {
e.preventDefault(); // 防止表单默认提交(若 button 在 form 内)
const settings = {
url: "https://dummyjson.com/users/13", // 示例 API,替换为你的真实 URL
method: "GET",
timeout: 5000,
headers: {
// "Authorization": "Bearer xxx",
// "Content-Type": "application/json"
}
// data: JSON.stringify({ inputData }), // POST 时启用
};
$.ajax(settings)
.done(function(response) {
// ✅ jQuery 已自动解析 JSON(若 Content-Type 正确为 application/json)
// response 已是 JavaScript 对象,无需 $.parseJSON() 或 JSON.parse()
const displayText = `<pre class="brush:php;toolbar:false;">${JSON.stringify(response, null, 2)}`;
$("#notif").html(displayText);
})
.fail(function(xhr, status, error) {
console.error("AJAX 请求失败:", status, error);
$("#notif").html(`❌ 请求失败: ${status}`);
})
.always(function() {
// 可选:加载状态清理,如隐藏 loading 动画
// $("#btPay").text("Go for Payment");
});
});
⚠️ 关键注意事项
- 不要重复解析 JSON:当服务器返回 Content-Type: application/json 时,jQuery 会自动将响应体解析为 JS 对象。调用 $.parseJSON(response) 或 JSON.parse(response) 会导致错误(因为 response 已是对象,非字符串)。
- 避免全局变量:像 var resJson 这样的全局状态易引发竞态、污染作用域,且无法保证赋值时机 —— 应始终通过回调参数传递数据。
-
.done() ≠ async/await:.done() 是 jQuery Deferred 的链式回调语法;若需 await,应改用原生 fetch() 或 $.ajax() 返回的 Promise(jQuery 3.0+ 支持):
async function myFunction() { try { const response = await $.ajax(settings); $("#notif").html(`<pre class="brush:php;toolbar:false;">${JSON.stringify(response, null, 2)}`); } catch (err) { console.error(err); $("#notif").text("请求出错"); } } - 推荐使用 .on() 替代已废弃的 .bind():bind() 自 jQuery 3.0 起已被标记为过时。
✅ 完整可运行示例(含 HTML)
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script><button id="btPay">Go for Payment</button>
<div id="notif" style="margin-top:16px; padding:12px; background:#f9f9f9; border-radius:4px;"></div>
<script>
$('#btPay').on('click', function(e) {
e.preventDefault();
$.ajax({
url: "https://dummyjson.com/users/13",
method: "GET"
})
.done(response => {
$("#notif").html(`<strong>✅ 用户信息:<pre class="brush:php;toolbar:false;">${JSON.stringify(response, null, 2)}</script>`);
})
.fail((xhr) => {
$("#notif").html(`❌ 错误 ${xhr.status}: ${xhr.statusText}`);
});
});
掌握异步流程控制是前端开发的核心能力。牢记:数据只在回调(或 then / await 后)中真正可用——把所有依赖响应的操作放进去,即可彻底规避“取不到值”的陷阱。











