function sleep(ms: number): Promise {
return new Promise(resolve => setTimeout(resolve, ms));
}
原理:
Promise
对象,在指定毫秒(ms
)后调用 resolve
结束等待。setTimeout
实现异步调度,避免阻塞主线程。async function demo() {
console.log("开始等待");
await sleep(2000); // 暂停 2 秒
console.log("等待结束");
}
demo();
输出:
开始等待
(2秒后)
等待结束
通过泛型扩展 sleep
功能,实现延迟后返回数据:
function sleep(ms: number, value?: T): Promise {
return new Promise(resolve =>
setTimeout(() => resolve(value), ms)
);
}
// 使用:延迟后返回字符串
async function fetchWithDelay() {
const data = await sleep(1000, "Hello, World!");
console.log(data); // 输出 "Hello, World!"
}
支持延迟中抛出异常:
function sleep(ms: number, shouldReject = false): Promise {
return new Promise((resolve, reject) => {
setTimeout(() => {
shouldReject ? reject(new Error("Sleep interrupted")) : resolve();
}, ms);
});
}
// 使用:模拟失败场景
async function riskyOperation() {
try {
await sleep(1000, true);
} catch (error) {
console.error(error.message); // 输出 "Sleep interrupted"
}
}
非阻塞特性
sleep
通过事件循环实现延迟,不会阻塞同步代码:
console.log("Start");
sleep(2000).then(() => console.log("Delayed"));
console.log("End");
// 输出:Start → End →(2秒后)→ Delayed
禁止同步滥用
在同步函数中调用 await sleep()
会导致整个函数暂停,但若在非 async
函数中使用会报错:
function syncFunction() {
await sleep(1000); // ❌ 语法错误:await 仅在 async 函数中有效
}
替代方案对比
方法 | 适用场景 | 缺点 |
---|---|---|
setTimeout |
简单回调场景 | 嵌套易导致回调地狱 |
Promise + sleep |
现代异步流程(推荐) | 需配合 async/await |
第三方库(如 bluebird ) |
复杂任务调度 | 增加依赖体积 |
接口轮询控制
async function pollAPI() {
while (true) {
const data = await fetchData();
if (data.status === "ready") break;
await sleep(5000); // 每 5 秒轮询一次
}
}
用户操作防抖
let searchTimer: number;
function onSearchInput(query: string) {
clearTimeout(searchTimer);
searchTimer = setTimeout(async () => {
await sleep(300); // 延迟 300ms 后执行搜索
runSearch(query);
}, 300);
}
动画序列控制
async function playAnimations() {
animateElement1();
await sleep(1000);
animateElement2();
await sleep(500);
animateElement3();
}
在 Node.js 中可复用 setTimeout
,或使用 setImmediate
实现微秒级延迟:
import { setTimeout } from "timers/promises"; // Node.js 16+
async function nodeSleep(ms: number) {
await setTimeout(ms);
}
最佳实践总结:
- ✅ 优先 Promise 方案:保持代码简洁与现代异步规范兼容;
- ⚠️ 避免同步思维:理解事件循环机制,禁止在非 async 函数中调用
await sleep()
;- 场景驱动设计:根据轮询、动画、防抖等需求选择合理延迟时长。