以正确的方式理解javascript中的油门

时间:2016-11-08 12:22:30

标签: javascript closures throttling

嗨,我试图了解javascript中的Throttling。 我有这个代码



function runOnce(fn, ms) {
  if(typeOf(fn) !== "function")
    return;
  ms = ms || 5000;
  var active;        
  return (function() {    	
         	if(active) {     
              console.log('no hurry please');      
            } else {
              active = setTimeout(fn, ms);      
            }
          })();      
};




我想使用两个不同的函数回调

进行测试
function x() {
   console.log('timeout from x');
}
function y() {
    console.log('timeout from y');
}

现在我的问题是: 多次调用runOnce(x);runOnce(x);runOnce(x);,油门功能似乎没问题(只调用功能x 一次)

  1. 但为什么呢 " console.log('不要急!'); "永远不会被援引?
  2. 当我致电runOnce(x);runOnce(x);runOnce(y);runOnce(y);时,功能x 功能y 仅被调用一次,这很好。

    1. 但为什么如果我拨打runOnce(x);runOnce(y);runOnce(x);runOnce(y);功能x 功能y 会被调用2次?
    2. 感谢

2 个答案:

答案 0 :(得分:0)

问题出在我的runOnce代码中。 如果我在函数之外移动 var active ,它就会被解决(感谢@Andreas的链接)。并修复一下这个功能。以下完整代码工作:

$('.dropbtn').mouseleave(function(e){
    var _this = $(this);
    hide_dropdown = setTimeout(function(){
        _this.next('.dropdown-content').removeClass('show');   
    },50);
});

$('.dropdown-content').hover(
    function(){
        clearTimeout(hide_dropdown);
    },
    function(){
        $(this).removeClass('show');
    }
);

答案 1 :(得分:0)

如何限制特定时间范围内的调用次数(例如调用 XYZ() ):

var throttleCallsObj = new Object;

function isCallBlocked(key, maxCallsPerFrame, mSecFrame)
{
    var nowDateTime = Date.now();

    if (typeof throttleCallsObj[key] === 'undefined')
        throttleCallsObj[key] = new Object;
    else
    {
        if (throttleCallsObj[key].dt > nowDateTime)
            return throttleCallsObj[key].nCalls >= maxCallsPerFrame;
    }
    throttleCallsObj[key].dt = nowDateTime + mSecFrame;
    throttleCallsObj[key].nCalls = 0;
    return false;
}


function countUnblockedCalls(key, mSecFrame)
{
    var nowDateTime = Date.now();

    if (typeof throttleCallsObj[key] === 'undefined')
        throttleCallsObj[key] = new Object;
    else
    {
        if (throttleCallsObj[key].dt > nowDateTime)
        {
            return (throttleCallsObj[key].nCalls += 1);
        }
    }
    throttleCallsObj[key].dt = nowDateTime + mSecFrame;
    throttleCallsObj[key].nCalls = 0;
    return 0;
}

用法:

function showMessage_A()
{
    if (isCallBlocked("typeA", 5, 200))
        return;

    /* your code ... */
     countUnblockedCalls("typeA", 200);
    XYZ();

}

function showMessage_B()
{
    if (isCallBlocked("typeB", 3, 200))
        return;

    /* your code ... */
     countUnblockedCalls("typeB", 200);
     XYZ();
}

countUnblockedCalls 是一个单独的函数,因为如果您的代码不调用 XYZ(),它可以被跳过。