limit.js

/**
 * 创建一个限流函数,该函数在时间间隔内只会执行一次。
 *
 * 与 `throttle` 的区别:
 * 1. 在时间间隔内再次调用,`limit`不会执行,而`throttle` 会执行;
 * 2. `limit` 没有取消和立即执行的方法,逻辑简洁。
 *
 * 与 `throttle(fn, wait, false)` 第三个参数为`false`的区别:
 * 1. 两者都是在间隔时间内只执行一次,但 `limit` 调用后立即执行,`throttle(fn, wait, false)` 调用后等待 wait 毫秒后执行。
 *
 * @alias module:Function.limit
 * @since 1.19.0
 * @param {Function} fn 要限流的函数。
 * @param {number} timespan 限流的时间间隔,单位为毫秒。
 * @returns 限流函数。
 * @example
 * function revalidate(){
 *   if(document.visibilityState !== 'hidden' || navigator.onLine){
 *     // do something
 *     console.log('revalidate');
 *   }
 * }
 *
 * // 限制 5s 内只会执行一次
 * const limited = limit(revalidate, 5000);
 *
 * window.addEventListener('visibilitychange', limited);
 * window.addEventListener('focus', limited);
 */
export default function limit(fn, timespan) {
    let pending = false;
    function limited(...args) {
        if (pending)
            return;
        pending = true;
        fn(...args);
        setTimeout(() => {
            pending = false;
        }, timespan);
    }
    return limited;
}