旧版JavaScript配合jQuery-steps如何等待异步校验完成后返回结果
问题原因
jQuery-steps 的
onStepChanging回调原生只支持同步返回布尔值,异步逻辑的返回值无法被回调外层捕获。你写的第二段代码中,fetch 是异步执行的,onStepChanging函数不会等待异步请求返回就会结束执行,默认返回的undefined会被插件判定为允许跳转,then 回调中返回的布尔值完全无法作用于跳转逻辑。
解决方案
优先采用「先阻止默认跳转+异步校验通过后主动触发跳转」的兼容方案,不需要修改插件源码,适配所有运行环境:
- 定义校验状态锁,用来标记当前步骤是否已经通过异步校验,避免重复发起请求
- 第一次触发
onStepChanging时先返回 false 阻止默认跳转,发起异步校验请求 - 异步校验通过后,将状态锁标记为通过,主动调用插件的
next方法触发下一步跳转 - 第二次触发
onStepChanging时,状态锁已标记为通过,直接返回 true 允许跳转即可
// 定义校验状态锁,作用域可根据你的代码结构调整(闭包/模块变量都可以) let isAsyncValidated = false; let isRequesting = false; // 额外加请求锁防止重复点击触发多次请求 onStepChanging: function (event, currentIndex, newIndex) { // 已经校验通过直接放行 if (isAsyncValidated) { // 放行后重置锁,方便返回上一步再次提交时重新校验 isAsyncValidated = false; return true; } // 请求中直接阻止跳转 if (isRequesting) { return false; } // 首次触发先阻止默认跳转,发起异步校验 isRequesting = true; fetch('/validate?username=' + $('#username').val()) .then(function(response) { return response.text(); // fetch返回的是Response对象,需要先提取响应文本 }) .then(function(result) { if (result == 'valid') { // 校验通过,标记状态锁 isAsyncValidated = true; // 主动触发下一步跳转,替换为你的表单选择器 $("#yourFormId").steps("next"); } else { // 校验失败,自定义用户提示即可 alert('用户名校验不通过'); } }) .catch(function() { alert('校验请求失败,请稍后重试'); }) .finally(function() { isRequesting = false; }); // 首次触发始终返回false阻止默认跳转 return false; }
不推荐备选方案
你也可以使用同步XMLHttpRequest实现等待返回效果,但同步请求会阻塞浏览器主线程,导致页面卡顿,仅作为极端场景下的备选:
onStepChanging: function (event, currentIndex, newIndex) { const xhr = new XMLHttpRequest(); // 第三个参数false代表同步请求 xhr.open('GET', '/validate?username=' + $('#username').val(), false); xhr.send(); return xhr.responseText === 'valid'; }
内容的提问来源于stack exchange,提问作者Ali EXE
相关产品推荐
相关产品推荐

