强调油门+确保最后一次通话

Pet*_*ich 5 javascript ajax timeout throttling underscore.js

Underscore提供方法,节流.从他们的文档:

创建并返回传递函数的新的受限制版本,当重复调用时,每次等待毫秒最多只调用一次原始函数.对于速度限制事件非常有用,这些事件发生得比您能跟上的速度要快.

现在想象一下自动填充表单的情况.这意味着如果在100ms窗口内输入"abc",则只会搜索"a",而不是"bc".

这是对underscore.js的严重疏忽吗?你会建议什么是干净的解决方案?

Ilj*_* KO 6

迟到了,但接受的答案是去抖函数而不是节流阀+我有一个更通用的节流函数,它可以充当正常或去抖版本,以确保在延迟结束后触发最后一个调用。因此,如果您愿意,基本上可以将油门和去抖合二为一

function throttle(f, delay = 0, ensure = false) {
  let lastCall = Number.NEGATIVE_INFINITY;
  let wait;
  let handle;
  return (...args) => {
    wait = lastCall + delay - Date.now();
    clearTimeout(handle);
    if (wait <= 0 || ensure) {
      handle = setTimeout(() => {
        f(...args);
        lastCall = Date.now();
      }, wait);
    }
  };
}
Run Code Online (Sandbox Code Playgroud)

怎么运行的:

  • 它首先是一个简单的节流函数,如果最后一次调用的时间早于当前调用的时间,您可以调用它delay
  • 您可以设置一个标志ensure来使节流函数确保最后一个调用在“帧”之间调用时将被调用
    • 例如,如果将函数限制为每秒 1 次调用,则意味着只有当最后一次调用时间超过 1 秒前时才会触发该函数
  • 如果您在启用标志的情况下调用节流函数ensure,而最后一次调用距离例如不到 1 秒(例如 600 毫秒),则节流函数只需设置一个超时以在 400 毫秒内调用该函数( -wait = lastCall + delay - Date.now()此处如果lastCall = 0delay = 1000Date.now() = 600超时将发生在400)
  • 否则,如果您希望将其视为简单的节流功能,则无需设置标志ensure,并且“帧”之间的调用将被忽略。

我认为这是一个优雅的解决方案,可以为简单的节流功能添加更多功能。我用它在编辑器中移动物体,同时保持重绘在一定的帧速率,但仍然确保仍然确保应用应该在帧之间发生的移动


小智 5

对于此用例,您可能希望使用以下“缓冲区”函数,该函数将仅应用等待窗口内的最后一次调用。

https://gist.github.com/2484196

_.buffer = function(func, wait, scope) {
  var timer = null;
  return function() {
    if(timer) clearTimeout(timer);
    var args = arguments;
    timer = setTimeout(function() {
      timer = null;
      func.apply(scope, args);
    }, wait);
  };
};
Run Code Online (Sandbox Code Playgroud)