MST

星途 面试题库

面试题:JavaScript定时器的嵌套与优化

假设有一个需求,需要每隔1秒打印数字1到10,然后再每隔2秒打印11到20。请使用setTimeout和setInterval实现该需求,并说明如何优化定时器嵌套可能带来的问题。
37.8万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

使用 setTimeoutsetInterval 实现

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();

优化定时器嵌套可能带来的问题

  1. 使用数组管理定时器:可以将定时器的返回值(setTimeoutsetInterval 的返回值)存储在数组中,以便在需要时能够方便地清除定时器。例如:
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();
  1. 使用 Promiseasync/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();

这种方式使得代码逻辑更加线性,易于理解和维护,同时也减少了回调地狱的问题。