async函数中设置location跳转后仍执行后续代码,如何阻止该行为?
解决方案
方案1:全局跳转标记法(侵入性最低,无需修改原有业务代码)
只需要3处小改动就能解决问题,完全不用动原有耦合的面条式点击逻辑:
- 新增全局跳转标记和跳转监听
// 全局变量,标记页面是否即将跳转 let isRedirecting = false; // 监听页面卸载事件,自动标记跳转状态,无需修改原有ajax逻辑 window.addEventListener('beforeunload', () => { isRedirecting = true; });
- 在你的主流程代码中每次等待请求完成后加一行判断即可:
$(document).on('click', 'input[name="shipping_method"]', async function () { await sleep(1); $('#button-shipping-method').click(); await waitForRequestsDone(); // 检测到即将跳转直接终止后续代码执行 if (isRedirecting) return; $('#button-payment-method').click(); await waitForRequestsDone(); });
方案2:封装等待请求逻辑,简化上层判断
如果希望代码更简洁,可以直接优化waitForRequestsDone函数,让它自动返回是否可以继续执行:
async function waitForRequestsDone() { ajaxWorking = true; let i=0; while (ajaxWorking) { // 每次循环先判断是否即将跳转 if (isRedirecting) return false; await sleep(50); i++; if(i>40) {break;} } return !isRedirecting; }
上层主流程可以简化为:
$(document).on('click', 'input[name="shipping_method"]', async function () { await sleep(1); $('#button-shipping-method').click(); if (!await waitForRequestsDone()) return; $('#button-payment-method').click(); await waitForRequestsDone(); });
原有sleep(1)生效的原因
你加的1ms等待是把后续代码推到了微任务队列末尾,刚好可以等ajax的同步回调先执行完拿到跳转状态,但这是概率性生效的方案,设备性能、网络波动时还是会触发异常,上面的标记方案是100%可靠的。
内容的提问来源于stack exchange,提问作者Roman K.
相关产品推荐
相关产品推荐

