SOURCE

console 命令行工具 X clear

                    
>
console
// lodash,在没有传入wait参数的情况下,优先使用requestAnimationFrame
// 如果浏览器不支持再降级使用setTimeout
// requestAnimationFrmae是比setInterval更搞笑更平滑的动画实现
// requestAnimationFrame
// 优势1:会把每一帧中所有元素变动在一次回流或者重绘中完成
// 优势2:在隐藏或者不可见的元素中,requestAnimationFrame不会进行重绘或回流

function debounce(fn, time) {
    if (typeof fn !== 'function') {
        throw new TypeError('Expected a function');
    }
    let timer = null;
    return function() {
        const context = this; // 保存作用域
        const args = arguments;
        if (!time && time !== 0 && typeof window.requestAnimationFrame === 'function') {
            console.log('window.requestAnimationFrame');
            window.cancelAnimationFrame(timer);
            timer = window.requestAnimationFrame(() => {
                fn.apply(context, args);
            });
            return;
        }
        clearTimeout(timer);
        timer = setTimeout(() => {
            fn.apply(context, args);
        }, time);
    }
}

function throttle(fn, time) {
    if (typeof fn !== 'function') {
        throw new TypeError('Expected a function');
    }

    let isFirstInvoke = true;
    let timerId = null;

    return function() {
        const args = arguments;
        const context = this;

        if (isFirstInvoke) {
            fn.apply(context, args);
            isFirstInvoke = false;
        }

        if (timerId) {
            return;
        }

        timerId = setTimeout(function(){
            clearTimeout(timerId);
            fn.apply(context, args);
            timerId = null;
        }, time )
    }
}

function test(a) {
    console.log(a);
}

const transferFn = debounce(test);
// const transferFn = throttle(test, 1000);

const btn = document.getElementById('button');

btn.addEventListener('click', () => {
    transferFn(222)
});
<button id="button">按钮</button>