函数节流

函数防抖

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
/**
 * 反反弹,延迟函数的执行。
 * 使用方法参照:http://underscorejs.org/#debounce
 * @param {*} func 函数
 * @param {*} wait 延迟事件
 * @param {*} immediate 是否马上执行
 */
export function debounce(func, wait, immediate) {
    let timeout, result;

    let later = function(context, args) {
        timeout = null;
        if (args) result = func.apply(context, args);
    };

    let debounced = function(...args) {
        if (timeout) clearTimeout(timeout);
        // 如果immediate为true,则立即执行
        if (immediate) {
            let callNow = !timeout;
            timeout = setTimeout(later, wait);
            if (callNow) result = func.apply(this, args);
        } else {
            timeout = setTimeout(() => {
                return later(this, args);
            }, wait);
        }
        return result;
    };

    debounced.cancel = function() {
        clearTimeout(timeout);
        timeout = null;
    };

    return debounced;
}

函数节流

/**
 * 创建并返回一个像节流阀一样的函数,当重复调用函数的时候,至少每隔 wait毫秒调用一次该函数。对于想控制一些触发频率较高的事件有帮助
 * 使用方法参照:http://underscorejs.org/#throttle
 * @param {*} func 回调
 * @param {*} wait 等待时间
 * @param {*} options 配置
 */
export function throttle(func, wait, options) {
    //初始化变量
    let timeout, context, args, result;
    let previous = 0;
    if (!options) options = {};

    //定义执行的方法
    let later = function() {
        previous = options.leading === false ? 0 : now();
        timeout = null;
        result = func.apply(context, args);
        if (!timeout) context = args = null;
    };

    //定义返回的节流方法
    let throttled = function() {
        let currentTime = now();
        //如果是首次并且leading === false 的时候,将previous设为now,这样now - previous,便不会大于wait。首次不执行
        if (!previous && options.leading === false) previous = currentTime;
        let remaining = wait - (currentTime - previous);
        context = this;
        args = arguments;
        // remaining小于等于0是跳出wait的限制,可以执行了
        // remaining大于wait的情况,只有在客户机修改了系统时间的时候才会出现(不太确定)
        // 这两种情况都可以立刻对func做调用
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = currentTime;
            result = func.apply(context, args);
            if (!timeout) context = args = null;
        } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining);
        }
        return result;
    };

    // 取消
    throttled.cancel = function() {
        clearTimeout(timeout);
        previous = 0;
        timeout = context = args = null;
    };

    return throttled;
}
上次更新: 11/23/2018, 12:28:05 AM