实现 sleep 延迟函数
使用 Promise 实现 JavaScript 的 sleep 函数
问题
实现一个 sleep / delay 函数,使代码暂停执行指定的时间。
async function main() {
console.log('开始');
await sleep(1000); // 暂停 1 秒
console.log('1秒后');
}
解答
基础实现
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 使用示例
async function demo() {
console.log('开始');
await sleep(1000);
console.log('1秒后执行');
}
demo();
带返回值的版本
function sleep(ms, value) {
return new Promise(resolve => setTimeout(() => resolve(value), ms));
}
// 使用示例
async function demo() {
const result = await sleep(1000, 'hello');
console.log(result); // 'hello'
}
可取消的 sleep
function sleep(ms) {
let timeoutId;
let rejectFn;
const promise = new Promise((resolve, reject) => {
rejectFn = reject;
timeoutId = setTimeout(resolve, ms);
});
// 添加取消方法
promise.cancel = () => {
clearTimeout(timeoutId);
rejectFn(new Error('Sleep cancelled'));
};
return promise;
}
// 使用示例
async function demo() {
const sleepPromise = sleep(5000);
// 2秒后取消
setTimeout(() => sleepPromise.cancel(), 2000);
try {
await sleepPromise;
console.log('完成');
} catch (e) {
console.log(e.message); // 'Sleep cancelled'
}
}
循环中使用
async function countdown(n) {
for (let i = n; i > 0; i--) {
console.log(i);
await sleep(1000);
}
console.log('结束');
}
countdown(3);
// 输出: 3 -> (1秒) -> 2 -> (1秒) -> 1 -> (1秒) -> 结束
关键点
sleep本质是用 Promise 包装setTimeout- 必须配合
async/await或.then()使用才能实现暂停效果 setTimeout的回调直接使用resolve,无需额外包装- 可取消版本需要保存
timeoutId并暴露cancel方法 - 在循环中使用时,必须用
for循环 +await,forEach无法正确等待
目录