【前端面试小册】JS-第29节:实现 sleep
一、核心概念
1.1 什么是 sleep
sleep 函数用于暂停程序执行指定的时间,常用于:
- 延迟执行
- 模拟异步操作
- 控制执行节奏
- 测试和调试
1.2 应用场景
- 延迟执行某些操作
- 控制请求频率
- 模拟网络延迟
- 动画控制
二、基础实现
2.1 Promise 版本
const sleep = (time) => {
return new Promise(resolve => setTimeout(resolve, time));
};
// 使用
sleep(1000).then(() => {
console.log('1秒后执行');
});
2.2 原理解析
执行流程:
graph TD
A[调用 sleep 1000] --> B[创建 Promise]
B --> C[设置 setTimeout]
C --> D[等待 1000ms]
D --> E[执行 resolve]
E --> F[Promise 完成]
F --> G[执行 then 回调]
关键点:
- 使用
Promise包装setTimeout setTimeout的回调中调用resolve- 返回
Promise,支持链式调用
三、增强版本
3.1 支持返回值
const sleep = (time, value) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(value);
}, time);
});
};
// 使用
sleep(1000, '完成').then(result => {
console.log(result); // '完成'
});
3.2 支持取消
function sleep(time) {
let timer = null;
let rejectFn = null;
const promise = new Promise((resolve, reject) => {
rejectFn = reject;
timer = setTimeout(() => {
resolve();
}, time);
});
promise.cancel = () => {
if (timer) {
clearTimeout(timer);
timer = null;
rejectFn(new Error('Sleep cancelled'));
}
};
return promise;
}
// 使用
const sleepPromise = sleep(5000);
sleepPromise.cancel(); // 取消延迟
3.3 支持进度回调
function sleep(time, onProgress) {
return new Promise((resolve) => {
const startTime = Date.now();
const interval = 100; // 每 100ms 更新一次
const timer = setInterval(() => {
const elapsed = Date.now() - startTime;
const progress = Math.min(elapsed / time, 1);
if (onProgress) {
onProgress(progress);
}
if (elapsed >= time) {
clearInterval(timer);
resolve();
}
}, interval);
});
}
// 使用
sleep(5000, (progress) => {
console.log(`进度: ${(progress * 100).toFixed(1)}%`);
}).then(() => {
console.log('完成');
});
四、async/await 使用
4.1 基础用法
const sleep = (time) => {
return new Promise(resolve => setTimeout(resolve, time));
};
// 使用 async/await
async function demo() {
console.log('开始');
await sleep(1000);
console.log('1秒后');
await sleep(1000);
console.log('2秒后');
}
demo();
4.2 循环中使用
async function processItems(items) {
for (const item of items) {
await processItem(item);
await sleep(1000); // 每个项目处理完后延迟 1 秒
}
}
4.3 并发控制
async function processWithDelay(items, delay) {
for (const item of items) {
await Promise.all([
processItem(item),
sleep(delay)
]);
}
}
五、实际应用场景
5.1 延迟执行
async function delayedAction() {
console.log('准备执行');
await sleep(2000);
console.log('2秒后执行');
// 执行某些操作
doSomething();
}
5.2 控制请求频率
async function fetchWithDelay(urls) {
const results = [];
for (const url of urls) {
const data = await fetch(url).then(r => r.json());
results.push(data);
await sleep(1000); // 每次请求间隔 1 秒
}
return results;
}
5.3 模拟网络延迟
async function mockFetch(url) {
await sleep(Math.random() * 1000); // 随机延迟 0-1 秒
return fetch(url);
}
5.4 动画控制
async function animate(element) {
for (let i = 0; i <= 100; i++) {
element.style.opacity = i / 100;
await sleep(10); // 每 10ms 更新一次
}
}
六、不同实现方式对比
6.1 Promise 版本(推荐)
const sleep = (time) => {
return new Promise(resolve => setTimeout(resolve, time));
};
优点:
- 简洁明了
- 支持 async/await
- 符合现代 JavaScript 规范
6.2 回调版本
function sleep(time, callback) {
setTimeout(callback, time);
}
缺点:
- 不支持 Promise
- 容易产生回调地狱
6.3 Generator 版本
function* sleepGenerator(time) {
yield new Promise(resolve => setTimeout(resolve, time));
}
// 使用
const gen = sleepGenerator(1000);
gen.next().value.then(() => {
console.log('完成');
});
缺点:
- 语法复杂
- 不常用
七、面试要点总结
核心知识点
- Promise 包装:使用
Promise包装setTimeout - async/await:支持现代异步语法
- 应用场景:延迟执行、控制频率、模拟延迟
- 扩展功能:支持取消、进度回调等
常见面试题
Q1: 如何实现 sleep 函数?
答:使用 Promise 包装 setTimeout,在回调中调用 resolve,返回 Promise 支持链式调用和 async/await。
Q2: sleep 函数有什么应用场景?
答:
- 延迟执行某些操作
- 控制请求频率
- 模拟网络延迟
- 动画控制
Q3: 如何实现可取消的 sleep?
答:保存 setTimeout 返回的 timer 和 Promise 的 reject 函数,提供 cancel 方法清除定时器并 reject Promise。
实战建议
- ✅ 理解 Promise 和 setTimeout 的结合使用
- ✅ 掌握 async/await 的使用
- ✅ 根据实际需求扩展功能(取消、进度等)
- ✅ 注意内存泄漏(及时清理定时器)
前端面试小册 文章被收录于专栏
每天更新3-4节,持续更新中... 目标:50天学完,上岸银行总行!

