节流

事件触发n秒后执行回调,在这n秒期间多次触发该回调不会执行回调函数,在n秒时执行,之后再触发。

简易版

function throttle(fn, delay) {
    if (typeof fn !== "function") throw new Error("第一个参数必须为函数!")
    let timer
    return function (...args) {
        if (timer) return
        timer = setTimeout(() => {
            fn.apply(this, args)
            timer = null
        }, delay)
    }

}

复杂版

funciton now() {
    return +new Date()
}

/**
 * underscore 节流函数,返回函数连续调用时,func 执行频率限定为 次 / wait
 *
 * @param  {function}   func      回调函数
 * @param  {number}     wait      表示时间窗口的间隔
 * @param  {object}     options   如果想忽略开始函数的的调用,传入{leading: false}。
 *                                如果想忽略结尾函数的调用,传入{trailing: false}
 *                                两者不能共存,否则函数不能执行
 * @return {function}             返回客户调用函数
 */
function throttle(fn, delay, options) {
    // 判断fn是否为函数
    if (typeof fn !== "function") throw new Error("第一个参数必须为函数")
    let context, args, result
    let timer = null
    let previous = 0
    if (!options) options = {}

    const later = () => {
        previous = options.leading === false ? 0, now()
        timer = null
        result = fn.apply(context, args)
        if (!timer) context = args = null
    }

    return function() {
        let nowDate = now()
        if (!previous && options.leading === false) previous = nowDate
        let remaining = delay - (nowDate - previous)
        context = this
        args = arguments
        if (remaining <= 0 || remaining > delay) {
            if (timer) {
                clearTimeout(timer)
                timer = null
            }
            previous = nowDate
            result = fn.apply(context, args)
            if (!timer) context = args = null
        } else if (!timer && options.trailing !== false) {
            timer = setTimeout(later, remaining)
        }
        return result
    }

}

results matching ""

    No results matching ""