Throttle JavaScript function calls, but with queuing (don't discard calls)

后端 未结 3 1925
醉梦人生
醉梦人生 2021-02-08 00:02

How can a function rate-limit its calls? The calls should not be discarded if too frequent, but rather be queued up and spaced out in time, X milliseconds apart. I\'ve looked at

3条回答
  •  鱼传尺愫
    2021-02-08 00:46

    Here is an example which carries forward this (or lets you set a custom one)

    function RateLimit(fn, delay, context) {
        var canInvoke = true,
            queue = [],
            timeout,
            limited = function () {
                queue.push({
                    context: context || this,
                    arguments: Array.prototype.slice.call(arguments)
                });
                if (canInvoke) {
                    canInvoke = false;
                    timeEnd();
                }
            };
        function run(context, args) {
            fn.apply(context, args);
        }
        function timeEnd() {
            var e;
            if (queue.length) {
                e = queue.splice(0, 1)[0];
                run(e.context, e.arguments);
                timeout = window.setTimeout(timeEnd, delay);
            } else
                canInvoke = true;
        }
        limited.reset = function () {
            window.clearTimeout(timeout);
            queue = [];
            canInvoke = true;
        };
        return limited;
    }
    

    Now

    function foo(x) {
        console.log('hello world', x);
    }
    var bar = RateLimit(foo, 1e3);
    bar(1); // logs: hello world 1
    bar(2);
    bar(3);
    // undefined, bar is void
    // ..
    // logged: hello world 2
    // ..
    // logged: hello world 3
    

提交回复
热议问题