不调用最后一个节流参数的节流阀

A throttle not calling the last throttled argument

上下文:我在一个javascript tutorial

的任务下写了一个简单的油门

任务:写一个像这样工作的油门:

function f(a) {
  console.log(a)
};

// f1000 passes calls to f at maximum once per 1000 ms
let f1000 = throttle(f, 1000);

f1000(1); // shows 1
f1000(2); // (throttling, 1000ms not out yet)
f1000(3); // (throttling, 1000ms not out yet)

// when 1000 ms time out...
// ...outputs 3, intermediate value 2 was ignored
// P.S. Arguments and the context this passed to f1000 should be passed to the original f.

这是我的解决方案。奇怪的是,当我 运行 它在调试控制台中逐步执行时它工作正常,但在其他情况下则不然。知道为什么以及如何解决它吗? (我假设它与setTimeout有关?)

function throttle(f, ms) {
  let isCoolDown = true,
  queue = []

  function wrapper(...args) {
    queue.push(args)

    if (!isCoolDown) return

    isCoolDown = false
    setTimeout(function() {
      isCoolDown = true
      if (queue[0] !== undefined) {
        f.apply(this, queue.slice(-1))
        queue = []
      }
    }, ms)

    return function() {
      f.apply(this, args)
      queue = []
    }()
  }
  return wrapper 
}

一些事情:

1) 交换 isCoolDown = falseisCoolDown = true

2) 你不需要队列,只有一个调用必须经过其他调用被限制丢弃


 function throttle(fn, ms) {
   let throttle = false;
   let timer;

   return wrapper(...args) {
     if(!throttle) { // first call gets through
        fn.apply(this, args);
        throttle = true;
     } else { // all the others get throttled
        if(timer) clearTimeout(timer); // cancel #2
        timer = setTimeout(() => {
          fn.apply(this, args);
          timer = throttle = false;
        }, ms);
     }
  };
}

这一行有错误:

f.apply(this, queue.slice(-1))

.slice 方法将 return 一个数组。由于 args 是一个数组,因此 queue.slice(-1) 的结果类似于:

[ [1, 2, 3] ]

相反,您可以将其更改为:

f.apply(this, queue.slice(-1)[0])