Aimee

personal blog

欢迎来到我的个人站~


常见代码题

用setTimeout 实现setInterval

let timer = null;
function mockSetInterval(fn, delay, ...args) {
    const recurFn = function() {
        timer = setTimeout(() => {
            fn.apply(this, atgs);
            recurFn();
        }, delay);
    }

    recurFn();
}

function mockClearInterval(id) {
    clearTimeout(id);
}

防抖和节流

防抖

  • 当持续触发事件时,一定时间内没有再触发事件,事件处理函数才会执行一次,如果一定时间内多次触发事件,就会重新开始延时

  • 最后一次事件触发后一定时间才会触发

适用场景

    function debounce(fn, wait) {
        let timer = null;
        return (...args) => {
            if(timer) {
                clearTimeout(timer);
            }

            timer = setTimeout(() => {
                fn.apply(this, args);
            }, wait);
        }
    }

节流

  • 当持续触发事件时,保证一段时间内只调用一次事件处理函数,当持续触发scroll事件的时候,每隔一定时间才会执行一次事件处理函数

适用场景

    // 时间戳,首节流,第一次立即执行,但是停止之后,没法再次执行
    function throttle(fn, interval) {
        let last = 0;
        return (...args) => {
            let now = Date.now();
            if(now - last >=  interval) {
                fn.apply(this, args);
                last = now;
            }
        }
    }

    // setTimeout  实现,尾节流,第一次不会立即执行,最后一次还会执行
    function throttle(fn, wait) {
        let timer = null;
        return (...args) => {
            if(!timer) {
                timer = setTimeout(() => {
                    fn.apply(this, args);
                    timer = null;
                })
            }
        }
    }

    // 结合
    function throttle(fn, wait) {
        let timer = null;
        let last = 0;
        return (...args) => {
            clearTimeout(timer);
            let now = Date.now();
            if(now - last >= wait) {
                fn.apply(this, args);
                last = now;
            } else {
                timer = setTimeout(() => {
                    fn.apply(this, args);
                }, wait);
            }
        }
    }