下划线节流+确保最后一次调用

问题描述 投票:0回答:6

Underscore提供了方法,throttle。来自他们的文档:

创建并返回所传递函数的新的、受限制的版本,当重复调用时,实际上每等待毫秒最多只会调用一次原始函数。对于发生速度比您跟不上的速度更快的速率限制事件很有用。

现在想象一下自动完成表单的情况。这意味着,如果在 100 毫秒窗口内键入“abc”,则只会发送对“a”的搜索,而不是“bc”。

这是 underscore.js 的严重疏忽吗?您建议什么作为干净的解决方案?

javascript ajax timeout throttling underscore.js
6个回答
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);
  };
};

3
投票

啊,我没有正确阅读文档!有 is 一个函数可以实现此目的。

var test = _.debounce(function() { console.log('foo'); }, 3000);

然后,如果您调用

test()
几次,您会注意到,只有在 last 调用后三秒后,才会调用该函数。

这正是我们都在寻找的东西......但没有注意到就在文档的throttle下方。


Underscore 文档

Lo-Dash 文档LoDash 是什么?


2
投票

https://gist.github.com/ayushv512/a2f963bface38f5e2f6f6bba39bba9b9#file-throttle-js

const throttle = (func, limit) => { let lastFunc; let lastRan; return function() { const context = this; const args = arguments; if (!lastRan) { func.apply(context, args) lastRan = Date.now(); } else { clearTimeout(lastFunc); lastFunc = setTimeout(function() { if ((Date.now() - lastRan) >= limit) { func.apply(context, args); lastRan = Date.now(); } }, limit - (Date.now() - lastRan)); } } }



2
投票

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

工作原理:

它首先是一个简单的节流函数,如果最后一次调用的时间早于
    delay
  • ,您可以调用它
    
    您可以设置一个标志
  • ensure
  • 来使节流函数确保最后一个调用在“帧”之间调用时将被调用
    例如,如果您将函数限制为每秒 1 次调用,则意味着只有当最后一次调用时间超过 1 秒前时才会触发
    如果您在启用
  • ensure
  • 标志的情况下调用节流函数,而最后一次调用是例如不到 1 秒的时间,例如600ms,那么受限制的函数只需设置一个超时,在 400ms 内调用该函数(
    wait = lastCall + delay - Date.now()
    - 这里如果
    lastCall = 0
    delay = 1000
    Date.now() = 600
    那么超时将在
    400
    内发生)
    否则,如果您希望将其视为简单的节流功能,只需不要设置 
  • ensure
  • 标志,并且“帧”之间的调用将被忽略。
    
    
  • 我认为这是一个优雅的解决方案,可以为简单的节流功能添加更多功能。我用它在编辑器中移动物体,同时保持以一定的帧速率重绘,但仍然确保仍确保应用应该在帧之间发生的移动



0
投票

© www.soinside.com 2019 - 2024. All rights reserved.