You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何仅延迟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

火山引擎 最新活动