2022/1/27

在一些时候,我们可以用一些高阶函数,也就是返回一个函数的函数,来实现一些比较高级的操作,比如说使某个方法只执行一次,或者限制执行的频率

Once 只执行一次

function once(fn) {
    return function (...args) {
        if (fn) {
            const ret = fn.apply(this, args);
            fn = null;
            return ret;
        }
    }
}

Throttle 限流函数

执行一次之后必须等待一段时间才能再执行

function throttle(fn, time = 500) {
    let timer;
    return function (...args) {
        if (timer == null) {
            fn.apply(this, args);
            timer = setTimeout(() => {
                timer = null;
            }, time)
        }
    }
}

Debounce 去抖

防止在指定时间段内多次触发函数,等待稳定(最后一次触发之后一定时间内没有再触发)才执行

function debounce(fn, dur) {
    dur = dur || 100;
    var timer;
    return function () {
        clearTimeout(timer);
        timer = setTimeout(() => {
            fn.apply(this, arguments);
        }, dur);
    }
}

Consumer 执行之间的最小间隔

方法每次调用必须至少间隔指定的时间,要是提前调用了,就先存起来,等到时间到了再调用。

与 Debounce 的区别就是,Debounce 在多次调用时会把多出来的舍弃掉,而 Consumer 会存起来慢慢调用

function consumer(fn, time) {
    let tasks = [],
        timer;

    return function (...args) {
        tasks.push(fn.bind(this, ...args));
        if (timer == null) {
            timer = setInterval(() => {
                tasks.shift().call(this)
                if (tasks.length <= 0) {
                    clearInterval(timer);
                    timer = null;
                }
            }, time)
        }
    }
}

Iterative

可以把一个普通的函数变成批量的,可以遍历第一个参数来执行

const isIterable = obj => obj != null
    && typeof obj[Symbol.iterator] === 'function';

function iterative(fn) {
    return function (subject, ...rest) {
        if (isIterable(subject)) {
            const ret = [];
            for (let obj of subject) {
                ret.push(fn.apply(this, [obj, ...rest]));
            }
            return ret;
        }
        return fn.apply(this, [subject, ...rest]);
    }
}

Toggle

可以循环执行多个函数,切换状态

function toggle(...actions) {
    return function (...args) {
        // 先将第一个操作取出,然后再将其 push 到列表的末尾,因此可以实现循环
        const action = actions.shift();
        actions.push(action);
        return action.apply(this, args);
    }
}

Code credits to 月影blog 好像炸了qwq)

来评论叭~
评论输入区域