我无法使用简单的油门功能

I can't get a simple throttle function to work

我知道还有很多其他人发布了有关节流功能的问题,我已经浏览了它们,但大多数(如果不是全部)都超出了我的水平,或者包括 jquery 之类的东西和非常奇怪的逻辑发挥作用。

我只是想限制用户每秒可以进行的更改次数,以阻止他们发送垃圾邮件。

我在 this youtube 视频的帮助下编写了我的代码,大部分情况下我都能理解。但是它似乎不起作用,我看不到任何问题或障碍。

这是我第一次尝试实现节流:

const throttle = (bad_func, limit) =>{
var flag = true;
document.getElementById('key').innerHTML = flag;
return function(){
  let context = this;
  let args = arguments;
  if(flag){
    bad_func.apply(context,args);
    bad_func();
    flag = false;
    setTimeout(()=>{
      flag = true;
    },limit);
  }
}
}

 ThrottledFunc = throttle(logKey, 4000);
 window.addEventListener('keydown', ThrottledFunc);

  function logKey(e){
  //           document.getElementById('EKey').innerHTML = e.which;
    if (e.which == 87){
     document.getElementById('demo').innerHTML = 'forwards';
     }

    else if (e.which == 83){
     document.getElementById('demo').innerHTML = 'backwards';
     }

    else{
     document.getElementById('demo').innerHTML = 'empty';
     }

     }

但是没用,我还是可以垃圾邮件w和s。 "demo" 变化但没有延迟。

对于我的第二次尝试,我只是说搞砸了并尝试将超时的事情实现到函数中,仍然没有运气:

window.addEventListener('keydown', logKey);

function logKey(e){
var flag = true;
var limit = 10000;
document.getElementById('key').innerHTML = flag;
if(flag){
  if (e.which == 87){
    flag = false;
    document.getElementById('demo').innerHTML = 'forwards';
    setTimeout(()=>{
      flag =true;
    }, limit);
  }

  else if (e.which == 83){
    document.getElementById('demo').innerHTML = 'backwards';
    flag = false;
    setTimeout(()=>{
      flag =true;
    }, limit);
   }
  }

else{
   document.getElementById('demo').innerHTML = 'empty';
  }
 }

我做错了什么?

几年前我做过类似的练习。

我最终想出了一个非常小的实现: throttled-event-listener.js

这是一个使用它的live demo

下面是 some docs 调用代码的样子。

希望对您有所帮助!

您需要构建一个闭包,这意味着变量 flag 必须在每次 logKey() 调用之间保留其值。解决方案是将其存储在全局(如下所示)或 logKey 可以访问它的父范围内。

window.addEventListener("keydown", logKey);

var flag = true;
var limit = 10000;

function logKey(e) {

  document.getElementById("key").innerHTML = flag;
  
  if (flag) {
    
    if (e.which == 87) {
      
      flag = false;
      document.getElementById("demo").innerHTML = "forwards";
      
      setTimeout(() => {
        flag = true;
      }, limit);
      
    } else if (e.which == 83) {
      
      document.getElementById("demo").innerHTML = "backwards";
      flag = false;
      
      setTimeout(() => {
        flag = true;
      }, limit);
      
    }
  } else {
    document.getElementById("demo").innerHTML = "empty";
  }
}
<div id="demo"></div>
<div id="key"></div>


我建议使用像 lodash 这样提供 throttle 功能的库。