Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 创建自己的油门功能并使用setTimeout进行测试_Javascript_Timeout_Throttling - Fatal编程技术网

Javascript 创建自己的油门功能并使用setTimeout进行测试

Javascript 创建自己的油门功能并使用setTimeout进行测试,javascript,timeout,throttling,Javascript,Timeout,Throttling,我有一个任务要写我自己的油门功能。它需要使用setTimeout通过一定数量的测试 这是我的代码: var throttle = function(func, delay) { var counter = 0; var calledOnce = false; setInterval(function(){ counter++; }, 1); return function() { if (counter > delay || !calledOnce) {

我有一个任务要写我自己的油门功能。它需要使用setTimeout通过一定数量的测试

这是我的代码:

var throttle = function(func, delay) {
  var counter = 0;
  var calledOnce = false;
  setInterval(function(){
    counter++;
  }, 1);
  return function() {
    if (counter > delay || !calledOnce) {
      calledOnce = true;
      counter = 0; 
      return func.apply(this, arguments);
    }
  };
};
我正在用以下方法对其进行测试:

var callBack = function () {
  console.log('called');
};

var func = throttle(callback, 1000);

func();                     // should be called
setTimeout(func, 500);      // should not be called
setTimeout(func, 1000);     // should be called
setTimeout(func, 1500);     // should not be called
setTimeout(func, 1900);     // should not be called
但是,当我按照这里的方式运行代码时,函数只被调用一次,使用原始的func()调用,并且setTimeout中的函数都没有被调用

我的代码或使用setTimeout进行测试是否有任何明显的问题?

代码中有什么问题:
  • setIntervalsetTimeout计算量大
  • 您的测试在单线程上运行,部署代码时会是这种情况吗?-不,我想不是。您可以记录调用函数的确切时间以及由哪个线程调用
  • 当您有高负载或多个线程检查它们是否应该执行时,我认为您将经历时间膨胀 仅仅因为您将其设置为以1ms的间隔运行,并不意味着该浏览器可以做到这一点。例如,如果我将其设置为0,强制它采用最小的可能间隔,并多次这样做以获得平均值,我发现我可以使用的最小间隔为~6 ms。在重载情况下,这会显著增加

    var start=newdate();
    var i=0,interval=setInterval(函数(){
    如果(++i>=1000){
    var end=新日期();
    var结果=(结束-开始)/1000;
    $(“#结果”).text(“平均间隔为”
    +结果+“毫秒”);
    $('#browser').text(navigator.userAgent);
    间隔时间;
    }
    }, 0);
    
    
    

    请等待大约10到20秒


    您需要清除间隔,因为无论您是否将间隔设置为零,它们都会增加计数器的值。如果您想调用其他函数,而不是只调用一个设置为false的calledOnce

    也许这个代码可以帮助你


    这将有助于:

    var throttle = function (input, delay) {
        var counter = 0;
        var calledOnce = false;
        var prev = Date.now();
    
        return function () {
            var now = Date.now();
            counter = now - prev;
            if (counter > delay || !calledOnce) {
                calledOnce = true;
                counter = 0;
                prev = now;
                return input.apply(null);
            }
        };
    };
    

    一个好的节流功能不需要大量的局部变量。节流功能的目的是减少浏览器资源,而不是应用太多的开销,使您使用的浏览器资源更多。作为这一主张的证据,我设计了一个节流函数,其范围内只有3个“挂起”变量。(一个“挂起”变量是一个永远不会被垃圾收集的变量,因为它总是被一个可能被调用的函数引用,从而占用内存。)请观察

    var timenow = self.performance?performance.now.bind(performance):Date.now;
    function throttle(func, minInterval) {
        var lastTimeWent = -minInterval;
        return function() {
            var newTimeWent = timenow();
            if ((newTimeWent-lastTimeWent) > minInterval) {
                lastTimeWent = newTimeWent;
                return func.apply(this, arguments);
            }
        };
    }
    
    使用您的示例进行测试:

    (函数(){“严格使用”;
    var timenow=self.performance?performance.now.bind(performance):Date.now;
    功能节流阀(func,最小间隔){
    var lasttimeGond=-minInterval;
    返回函数(){
    var newtimego=timenow();
    如果((NewTimeGond LastTimeGond)>minInterval){
    LastTimeGond=NewTimeGond;
    返回函数apply(这是参数);
    }
    };
    }
    var callBack=函数(){
    console.log('\tcall!');
    };
    var func=节流阀(回调,1000);
    var start=timenow();
    包装器();//应该被调用
    setTimeout(包装器,500);//不应调用
    setTimeout(包装器,1000);//应被调用
    setTimeout(包装器,1500);//不应调用
    setTimeout(wrapper,1900);//不应调用
    异步函数包装器(){
    log(“在“+Math.round(timenow()-start)+”ms..”之后调用”;
    func();
    log(“完成呼叫!”);
    }
    
    })();您只调用一次油门,它设置为
    calledOnce=truevar timenow = self.performance?performance.now.bind(performance):Date.now;
    function throttle(func, minInterval) {
        var lastTimeWent = -minInterval;
        return function() {
            var newTimeWent = timenow();
            if ((newTimeWent-lastTimeWent) > minInterval) {
                lastTimeWent = newTimeWent;
                return func.apply(this, arguments);
            }
        };
    }