Ajax执行顺序混乱问题求助(附Java Servlet相关代码)
搞定Ajax执行顺序混乱的问题
嘿,我一眼就看出你遇到的是Ajax异步特性搞出来的执行顺序坑了——默认情况下Ajax请求是异步的,你的chkUser()函数会在Ajax请求还没拿到Servlet的响应时,就直接返回初始值了,导致后面的代码拿到的根本不是你想要的验证结果。
先把你没写完的chkUser()代码补全(我猜你这里是调用Java Servlet做用户验证对吧?),完整的大概是这样:
function chkUser() { alert("inside chk"); var result = false; $('#subbutton').focus(); if ($("#user").val().length < 8) { alert("User ID must be atleast 8 digits"); result = false; } else if ($("#user").val().length > 10) { alert("User ID must not exceed 10 digits"); result = false; } else { // 这里应该是你调用Servlet的Ajax请求 $.ajax({ url: "YourServlet", type: "POST", data: {user: $("#user").val()}, success: function(response) { // 假设Servlet返回"true"表示用户合法 result = (response === "true"); } }); } return result; }
为啥会乱序?
默认的$.ajax是异步模式,也就是说当你发起Ajax请求后,JavaScript不会傻等着请求完成,而是直接跳到后面的return result语句。这时候result还是你一开始设的false,所以你会先看到alert('out ' + a)弹出out false,等Ajax请求真正拿到Servlet的响应时,success回调里才会修改result,但这时候函数早就返回了,根本没用。
怎么解决?
方案1:改成同步Ajax(不推荐,别轻易用)
可以把Ajax设为同步,这样JavaScript会等请求完成再继续执行。但这种方式会卡死浏览器,用户在请求完成前啥都点不了,体验特别差:
function chkUser() { alert("inside chk"); var result = false; $('#subbutton').focus(); if ($("#user").val().length < 8) { alert("User ID must be atleast 8 digits"); result = false; } else if ($("#user").val().length > 10) { alert("User ID must not exceed 10 digits"); result = false; } else { $.ajax({ url: "YourServlet", type: "POST", data: {user: $("#user").val()}, async: false, // 关键:改成同步 success: function(response) { result = (response === "true"); } }); } return result; }
方案2:用回调函数(推荐,简单实用)
更好的办法是用回调函数,把需要等验证完成后才执行的逻辑放到回调里,这样既不卡页面,顺序也对:
$('#subbutton').on("click", function(e) { e.preventDefault(); // 先阻止表单默认提交,不然可能直接跳走了 alert("1"); // 调用chkUser时传一个回调函数,等验证完再执行 chkUser(function(isValid) { alert('out ' + isValid); if (isValid) { // 这里应该是你原本的判断逻辑,比如合法才提交表单 $("#formid").submit(); } }); }); function chkUser(callback) { alert("inside chk"); $('#subbutton').focus(); var userVal = $("#user").val(); if (userVal.length < 8) { alert("User ID must be atleast 8 digits"); callback(false); // 验证不通过,调用回调传false } else if (userVal.length > 10) { alert("User ID must not exceed 10 digits"); callback(false); } else { $.ajax({ url: "YourServlet", type: "POST", data: {user: userVal}, success: function(response) { // 请求成功,把验证结果传给回调 callback(response === "true"); }, error: function() { // 请求失败也告诉回调验证不通过 callback(false); } }); } }
方案3:用Promise(更现代的写法)
如果你的项目支持ES6+,用Promise会让代码更清晰,还能配合async/await用:
$('#subbutton').on("click", async function(e) { e.preventDefault(); alert("1"); try { // 用await等待chkUser的Promise完成 var isValid = await chkUser(); alert('out ' + isValid); if (isValid) { $("#formid").submit(); } } catch (err) { alert("验证出错啦!"); } }); function chkUser() { // 返回一个Promise对象 return new Promise((resolve, reject) => { alert("inside chk"); $('#subbutton').focus(); var userVal = $("#user").val(); if (userVal.length < 8) { alert("User ID must be atleast 8 digits"); resolve(false); // 验证不通过,resolve传false } else if (userVal.length > 10) { alert("User ID must not exceed 10 digits"); resolve(false); } else { $.ajax({ url: "YourServlet", type: "POST", data: {user: userVal}, success: function(response) { resolve(response === "true"); // 请求成功,返回验证结果 }, error: function(xhr) { reject(xhr); // 请求失败,抛出错误 } }); } }); }
最后说一句
优先选回调或者Promise的方式,别用同步Ajax,毕竟用户体验才是第一位的。这样改完,代码的执行顺序就完全符合你的预期啦!
内容的提问来源于stack exchange,提问作者muhammed aslam
相关产品推荐
相关产品推荐

