绝地武士式睡眠:2025年JavaScript中sleep()的完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么JavaScript没有标准的sleep()?

\n

大家好,开发者同仁们!如果你曾经从Python、PHP或Java转向JavaScript,你肯定会问过这个问题:“我钟爱的sleep(1)在哪里,好让程序暂停一秒钟?”。然后,在翻阅文档后,你会惊讶地发现纯JS中并没有这样的函数。

\n

这不是一个缺陷,而是一个特性。JavaScript是一种单线程语言,运行在事件循环(Event Loop)中。如果我们简单地阻塞线程一秒钟,整个界面都会随之冻结,点击、动画和请求都将停止处理。阻塞式的sleep()是Web开发中的反模式。

\n

但这并不意味着我们不能实现暂停。在Stack Overflow上,“What is the JavaScript version of sleep()?”这个问题获得了数十万次浏览,而到了2025年,我们拥有一整套解决方案——从简单到复杂。

\n

在这篇文章中(专为教育门户网站pythonlib.ru编写),我们将分析所有让JavaScript“休眠”的合法方法,它们的优缺点,并为不同场景确定最佳实践。

\n\n

最正确的方法:async/await和Promise

\n

从ES2017开始,JavaScript引入了增强版异步——async/await。如果你想在不阻塞主线程的情况下实现暂停,你需要一个返回Promise的函数,该Promise会在指定时间后解决。

\n

这就是我们为2025年定制的sleep()函数:

\n\n
// 通用延迟函数\nfunction sleep(ms) {\n    return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n// 使用示例\nasync function demo() {\n    console.log('开始...');\n    await sleep(2000); // 等待2秒\n    console.log('2秒过去了!');\n}\n\ndemo();\n
\n\n

这是一个非阻塞的sleep。当执行await sleep(2000)时,其余代码(事件处理程序、其他异步函数)继续运行。事件循环不会休眠——它只是将后续代码行的执行推迟到Promise解决之后。

\n\n

为什么这是最佳实践?

\n
    \n
  • 不阻塞UI——界面保持响应。
  • \n
  • 标准语法——读起来像普通的同步代码。
  • \n
  • 适用于Node.js——服务器不会挂起。
  • \n
  • 广泛支持——现代浏览器和Node.js 8+。
  • \n
\n\n

老牌方法:setTimeout()

\n

在async/await时代之前,我们使用setTimeout()。它仍然存在且有效,但需要回调函数,这会导致“回调地狱”。

\n\n
console.log('开始');\nsetTimeout(() => {\n    console.log('1.5秒过去了');\n}, 1500);\nconsole.log('结束(立即执行)');\n
\n\n

控制台输出将是:开始,然后是结束(立即),最后才是1.5秒过去了。这并非传统意义上的sleep(),但对于简单场景来说非常理想。

\n\n

何时使用setTimeout?

\n
    \n
  • 当需要在一段时间后执行一次操作时。
  • \n
  • 在动画中(例如,在300毫秒后启动一个效果)。
  • \n
  • 在逻辑不复杂的简单脚本中。
  • \n
\n\n

阻塞式sleep(以及为什么不应该这样做)

\n

是的,从技术上讲,你可以通过一个空循环来冻结线程。但这纯粹是邪恶的。

\n\n
function blockSleep(milliseconds) {\n    const start = Date.now();\n    while (Date.now() - start < milliseconds) {\n        // 空循环——CPU发热,标签页卡死\n    }\n}\n\nconsole.log('开始');\nblockSleep(3000);\nconsole.log('3秒过去了(但浏览器卡死了)');\n
\n\n

这段代码完全按照你的要求执行:停止执行

博客

书籍推荐