JavaScript用setTimeout实现setInterval,以及clearInterval

953 阅读1分钟

实现setInterval

在平时面试过程中经常会遇到手写代码的面试题,今天就来实现实现setTimeout实现setInterval;

首先,想到实现反复调用,我们第一印象想到递归和循环,今天我们就用递归来实现;

function myInterval(func, time) {

    function fn() {

        let id = setTimeout(() => {

            func();//调用传进来的函数

            fn();//递归调用fn,实现setInterval

        }, time)

    }

    fn();

}

实现clearInterval

现在,就让我们想想怎么清除这么多的定时器吧;

首先我们会想到这么多定时器怎么清理呢?我们想想setTimeout和setInterval怎么清除的呢?原来他们是通过定时器返回的id进行清除的,所以我们有什么方法手机所有的setTimeout的id呢?我们想到了用数组来收集,并且得返回出去让外面变量能接受到。所以myInterval修改为下面这样子;

function myInterval(func, time) {

    let ids = [];//收集所有定时器id

    function fn() {

        let id = setTimeout(() => {

            func();//调用传进来的函数

            fn();//递归调用fn,实现setInterval

        }, time)

        ids.push(id);

    }

    fn();

    return ids;//把所有id返回出去

}

现在我们收到所有定时器的id了,接下来让我们实现clearInterval吧;

首先ids是一个数组,存放着我们所有的id,所以我们可以通过遍历数组的元素来清除定时器;

let id = myInterval(() => {

    document.console('Hello World');

}, 500)//收集到所以id

//开始实现clearInterval
function clearMyInterval(idList) {

    idList.forEach((id) => {//遍历每一个id
    
        clearTimeout(id);//清除定时器
        
    })

}

最终代码

function myInterval(func, time) {

    let ids = [];

    function fn() {

        let id = setTimeout(() => {

            func();

            fn();

        }, time)

        ids.push(id);

    }

    fn();

    return ids;

}

let id = myInterval(() => {

    document.write('Hello World');

}, 500)


function clearMyInterval(idList) {

    idList.forEach((id) => {

        clearTimeout(id);

    })

}

setTimeout(() => {

    clearMyInterval(id)

}, 3000)