使用async/await后向导beforeNextStep中return false不生效如何解决
问题根因
你遇到的逻辑失效问题本质是async函数的返回值特性和原插件的同步判断逻辑不兼容导致的:
- 所有
async函数无论内部返回什么值,最终返回的都是Promise对象,而非普通布尔值 - 原插件默认的
beforeNextStep是同步函数,插件内部调用时会直接将返回值做布尔判断,Promise对象本身属于真值,所以无论你内部返回true还是false,插件都会直接判定为允许进入下一步,这就是校验失败返回false不生效的核心原因。
修复步骤
1. 调整插件调用逻辑(必做)
你有两种可选方案,根据你是否能修改插件源码选择:
方案A:修改插件源码支持异步回调
找到插件内部调用beforeNextStep的位置,将原来的同步判断改为异步等待:
原插件内的逻辑大概是这样的:
// 原插件内的下一步点击处理逻辑(同步) if (options.beforeNextStep(currentStep)) { goToNextStep(); }
修改为支持异步的版本:
// 先把点击处理函数改为async $nextBtn.on('click', async function() { const canGoNext = await options.beforeNextStep(currentStep); if (canGoNext) { goToNextStep(); } })
方案B:不修改插件源码,自定义点击事件拦截
如果无法修改插件源码,可以不依赖插件的beforeNextStep回调,自己绑定下一步按钮的点击事件,校验和AJAX逻辑都自己处理,完成后手动调用插件的下一步方法:
// 先取消插件自带的下一步按钮事件,自己绑定 $('.btn-primary.float-right').off('click').on('click', async function() { const currentStep = 获取当前步骤的方法(); // 你的校验和AJAX逻辑 const canGoNext = await 你的校验逻辑函数(currentStep); if (canGoNext) { // 手动调用插件的下一步方法 $("#mydiv").accWizard('next'); } })
2. 修复你自定义函数内的返回值逻辑
你当前在$.ajax的done回调里返回true/false是无效的,done回调的返回值不会作为整个async函数的返回值,需要把逻辑从done回调挪到await之后:
beforeNextStep: async function (currentStep) { if($('#smartcheckin' + currentStep).valid()){ // 先解绑避免重复绑定提交事件 $('#smartcheckin' + currentStep).off('submit').on('submit', () => false); if ($('#documento_caricato' + currentStep).val() == '') { swal.fire('SmartCheckin', 'Devi caricare un documento per proseguire', 'warning'); return false; } const data = $('#smartcheckin'+ currentStep).serialize(); // 等待AJAX返回,不要用done回调 const res = await $.ajax({ type: 'POST', dataType:'JSON', url: 'endpoints/checkin.php', data: data, }); if(res.status==200){ Toast.fire({icon: 'success',title: 'Checkin effettuato correttamente'}); if(currentStep<allSteps){ return true; }else{ location.href="thankyou.html?token="+token; return false; } }else{ // 提交错误报告 await $.ajax({ "url": "/mantisbt/api/rest/issues", "method": "POST", "timeout": 0, "headers": { "Authorization": "3O4DtX_cwU9d57FRGdVhi6qCagUNFU1E", "Content-Type": "application/json" }, "data": JSON.stringify({ "summary": res.message.summary, "description": res.message.description, "additional_information": res.message.additional_information, "project": { "id": 1, "name": "smartreservation"}, "category": {"id": 5, "name": "bugtracker"}, "handler": {"name": "lelio"}, "view_state": {"id": 10,"name": "public"}, "priority": {"name": "normal"}, "severity": {"name": "crash"}, "reproducibility": {"name": "sometimes"}, "sticky": false, }) }); Toast.fire({ icon: 'error', title: 'Problemi a effettuare il checkin. Una segnalazione è stata aperta al nostro reparto tecnico' }); return false; } }else{ console.log('false returned'); return false; } },
3. 关于默认函数是否要改async
如果采用方案A修改了插件源码支持异步回调,默认函数不需要强制修改为async:
await关键字兼容普通返回值,await true会直接返回true,和异步返回的结果处理逻辑一致- 当然你也可以把默认函数改成async版本,不会有兼容问题:
beforeNextStep: async function (t) { return !0 }
内容的提问来源于stack exchange,提问作者user2399035
相关产品推荐
相关产品推荐

