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

时间:2018-09-30 08:50:34

标签: javascript throttling

上下文:我在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 
}

2 个答案:

答案 0 :(得分:1)

几件事:

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);
     }
  };
}

答案 1 :(得分:0)

此行有一个错误:

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

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

[ [1, 2, 3] ]

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

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