JavaScript中实现sleep功能的方法

JavaScript中实现sleep功能的方法

技术背景

在JavaScript里,并没有像其他编程语言那样原生的 sleep() 函数。这是由于JavaScript采用单线程事件驱动模型,若实现阻塞式的 sleep() 会让整个程序陷入停顿,从而影响用户体验。不过,在一些场景下,我们的确需要实现类似“休眠”的功能,比如在执行某个操作后等待一段时间再执行下一个操作。

实现步骤

1. 使用Promise和setTimeout实现

可以借助 PromisesetTimeout 来实现 sleep 功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

// 使用示例
async function demo() {
for (let i = 0; i < 5; i++) {
console.log(`Waiting ${i} seconds...`);
await sleep(i * 1000);
}
console.log('Done');
}

demo();

2. 单行程写法

1
await new Promise(r => setTimeout(r, 2000));

3. 作为函数

1
const sleep = ms => new Promise(r => setTimeout(r, ms));

4. TypeScript实现

1
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));

5. 不同运行环境的实现

Node.js 16+

1
2
3
import {setTimeout} from 'timers/promises';

await setTimeout(1000); // Sleep for 1 second

Bun.js

1
await Bun.sleep(1000); // Sleep for 1 second

核心代码

通用实现

1
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

TypeScript带Abort Signal实现

1
2
3
4
5
6
7
8
9
const wait = (x: number, signal?: AbortSignal): Promise<number> => {
return new Promise((s, f) => {
const id = setTimeout(s, x, x);
signal?.addEventListener('abort', () => {
clearTimeout(id);
f('AbortError');
});
});
};

最佳实践

  • 使用 async/await:在 async 函数里使用 await sleep() 能让代码更具可读性。
  • 避免阻塞主线程:尽量别使用阻塞式的 sleep 实现,以免影响用户体验。
  • 考虑兼容性:要是需要兼容旧版本的Node.js或者浏览器,可以使用Babel进行转译。

常见问题

1. await 只能在 async 函数中使用

await 只能在以 async 关键字修饰的函数中执行,或者在部分支持的环境里的脚本顶层使用。

2. 阻塞式 sleep 不可取

阻塞式的 sleep 会让整个线程陷入停顿,影响程序性能和用户体验。大多数情况下,建议使用非阻塞式的 sleep 实现。

3. 浏览器对某些特性支持有限

例如 Atomics.wait 在浏览器中的支持极为有限,大部分浏览器不允许在主线程使用。


JavaScript中实现sleep功能的方法
https://119291.xyz/posts/2025-05-09.javascript-sleep-function-implementation/
作者
ww
发布于
2025年5月9日
许可协议