面试题答案
一键面试使用 setTimeout
和 setInterval
实现
function printNumbers() {
let i = 1;
const printFirstSet = () => {
if (i <= 10) {
console.log(i);
i++;
setTimeout(printFirstSet, 1000);
} else {
i = 11;
const printSecondSet = () => {
if (i <= 20) {
console.log(i);
i++;
setTimeout(printSecondSet, 2000);
}
};
printSecondSet();
}
};
printFirstSet();
}
printNumbers();
优化定时器嵌套可能带来的问题
- 使用数组管理定时器:可以将定时器的返回值(
setTimeout
或setInterval
的返回值)存储在数组中,以便在需要时能够方便地清除定时器。例如:
const timerArray = [];
function printNumbers() {
let i = 1;
const printFirstSet = () => {
if (i <= 10) {
console.log(i);
i++;
const timer = setTimeout(printFirstSet, 1000);
timerArray.push(timer);
} else {
i = 11;
const printSecondSet = () => {
if (i <= 20) {
console.log(i);
i++;
const timer = setTimeout(printSecondSet, 2000);
timerArray.push(timer);
}
};
printSecondSet();
}
};
printFirstSet();
// 假设在某个时候需要清除所有定时器
setTimeout(() => {
timerArray.forEach(timer => clearTimeout(timer));
}, 5000);
}
printNumbers();
- 使用
Promise
或async/await
简化嵌套:将定时器操作封装成Promise
,这样可以使用async/await
来编写更清晰的代码,避免层层嵌套。
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function printNumbers() {
for (let i = 1; i <= 10; i++) {
console.log(i);
await delay(1000);
}
for (let i = 11; i <= 20; i++) {
console.log(i);
await delay(2000);
}
}
printNumbers();
这种方式使得代码逻辑更加线性,易于理解和维护,同时也减少了回调地狱的问题。