如何仅延迟wait函数后的代码,而非整个代码块?
解决JS中仅延迟后续代码的问题
嘿,这个问题我太熟了!你写的wait函数是同步阻塞的,它会霸占着JavaScript的单线程事件循环不放,导致整个页面包括之前的代码都没法正常执行,自然就会感觉整个代码块都被延迟了。
为什么你的wait函数会阻塞整个代码?
JavaScript是单线程语言,当你用while循环不断检查时间差时,这个循环会一直占用线程,浏览器根本没时间处理其他任务(比如UI渲染、用户交互),直到循环结束。这就导致整个页面都卡住了,而不是只延迟你想要的那段代码。
正确的解决方案:用异步方式实现延迟
下面两种方法都能实现“仅延迟后续代码”的效果,而且不会阻塞页面:
方法1:使用setTimeout(最常用)
把需要延迟执行的代码放到setTimeout的回调函数里,它是异步的,不会阻塞当前线程:
function cardChecker(e){ if(e.target === prevElement){ // 延迟1秒后执行alert setTimeout(() => { alert('Please select another square!'); }, 1000); return; } // 其他代码不受延迟影响,会正常执行 e.target.firstChild.classList.toggle('hid... }
setTimeout会把回调函数加入事件队列,等当前所有同步代码执行完,再过指定时间才执行回调,完全不会阻塞前面的逻辑。
方法2:用async/await(更优雅的语法糖)
先把wait函数改成返回Promise的异步函数,再用async/await来控制流程:
// 重写wait为异步函数 function wait(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // 把cardChecker改成async函数 async function cardChecker(e){ if(e.target === prevElement){ await wait(1000); // 仅暂停当前函数后续代码,不阻塞全局线程 alert('Please select another square!'); return; } // 其他代码正常执行 e.target.firstChild.classList.toggle('hid... }
await会暂停当前async函数的执行,等待Promise完成,但不会阻塞整个浏览器的事件循环,页面其他部分依然能正常响应。
注意事项
一定要抛弃原来的同步wait函数,它会导致页面卡顿,严重影响用户体验。异步延迟才是JavaScript中处理这类需求的正确方式。
内容的提问来源于stack exchange,提问作者Aditya Gorti




