在 JavaScript 中实现“睡眠等待”(延迟执行)通常有以下几种方法,具体选择取决于你的使用场景(如浏览器环境、Node.js 或异步代码流):
1. setTimeout
+ 回调函数
最基础的延迟执行方法,但会导致回调地狱(Callback Hell):
function sleep(ms, callback) {
setTimeout(callback, ms);
}
// 使用
sleep(2000, () => {
console.log("2秒后执行");
});
2. Promise
+ setTimeout
(推荐)
用 Promise 封装,支持 async/await
语法:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 用法1:then链式调用
sleep(2000).then(() => {
console.log("2秒后执行");
});
// 用法2:async/await(需在async函数内)
async function demo() {
await sleep(2000);
console.log("2秒后执行");
}
demo();
3. ES2022 Atomics.waitAsync
(高级场景)
适用于需要精确控制的场景(如 Worker 线程同步):
// 仅在支持 SharedArrayBuffer 的环境中使用
function highPrecisionSleep(ms) {
const sharedBuf = new SharedArrayBuffer(4);
const sharedArr = new Int32Array(sharedBuf);
return Atomics.waitAsync(sharedArr, 0, 0, ms).value;
}
// 使用
highPrecisionSleep(2000).then(() => {
console.log("高精度等待2秒");
});
注意:此 API 对运行环境有严格要求(如 HTTP 响应头需配置 COOP
/COEP
)。
4. Node.js 特有方法
(1) setImmediate
/ process.nextTick
微任务队列控制(非真正“睡眠”):
// nextTick优先于其他I/O事件
process.nextTick(() => {
console.log("下一个事件循环执行");
});
(2) timers/promises
(Node.js v15+)
原生 Promise-based API:
import { setTimeout } from 'timers/promises';
await setTimeout(2000); // 直接使用
5. Busy Waiting (不推荐)
阻塞主线程的暴力方法(仅用于特殊调试):
function busyWait(ms) {
const start = Date.now();
while (Date.now() - start < ms) {}
}
busyWait(2000); // ❌页面会卡死!
警告:这种方法会冻结 UI/主线程,永远不要在生产环境使用!
最佳实践建议
场景 | 方案 | 备注 |
---|---|---|
通用延迟 | Promise + setTimeout | 兼容性好 |
Node.js | timers/promises | 代码最简洁 |
高精度需求 | Atomics.waitAsync | 环境要求严格 |
避免阻塞 | 永远不用busy wait | - |
如果需要在 循环中依次延迟,可以结合 for
+ await
:
“`javascript
async function delayedLoop() {
for (let i = 0; i < 5; i++) {
await sleep(1000);
console.log(`第${i+1}次输出`);
}
}
delayedLoop();
“`
内容由零声教学AI助手提供,问题来源于学员提问