JavaScript奇淫技巧(一) -----防抖动&&节流

实际中我们常会遇到绑定事件触发函数的情况,每次触发事件就调用函数执行逻辑或者是与后台交互

正常情况下这样做并没有问题,但是有的时候事件是高频触发的,而绑定的函数相对来说是一个代价比较大的函数,这样会降低程序的性能或者是影响用户体验.

举个例子:

  有一个单据,需要根据金额的不同,展现不同的处理流程:如(0,10) 是A  (10,100) 是B (100,1000)是C

  并且流程应该是实时获取的.

  可以这样实现 对金额输入框绑定一个keyUp事件 然后事件中触发获取流程的方法 

 1  $("#amount").keyup(function(){
 2     GetApprove($("#amount").val())
 3  })
 4 //其实应该这样写,可以避免在安卓捕获不到删除按钮的事件
 5  document.getElementById("amount").addEventListener("input", function () {
 6     GetApprove($("#amount").val())
 7 }, false);
 8 
 9  var GetApprove=function(amount){
10     //获取流程
11  }

  这样的话,每次松开按键就会触发获取流程的方法,这样就能根据当前输入的金额获取到最新的数据了

  但是这样有一个问题,当用户输入的金额是1000的时候,就会连续的触发四次请求,四次请求传递的金额是1, 10, 100, 1000

  然而我们实际上只需要的是1000这次请求的返回结果,(并且如果你代码没有做任何处理的话,因为间隔时间短,再加上网络原因等,有可能请求返回的结果不是按发出的顺序返回,

  可能是返回的10,1,100,1000 这样一个序列 最后导致用户获取的实际上是100的流程.这一个暂且不论在下一篇处理好了)

  这样的话实际上浪费了三次请求,也就是说你的cpu压力加大了四倍

  

  如何解决这个问题,可以这样处理:(防抖动Debounce) 

 var actionId=0; //设为全局变量
 var GetApprove=function(amount){
    clearTimeout(actionId);
    actionId=setTimeout(function() {
        //获取流程
    }, 300);
 }

  即每次操作都延时300ms处理,如果在300ms内中有新的操作则重新延时300ms并取消上一个操作.

  这样的话就解决了频繁触发的问题,当用户正常输入1000的时候,虽然触发了1 10 100 1000四个操作 但是实际上只有最后一个操作真正被执行

  查看了一下相关资料 可写这样一个方法

  

    function Debounce(method,context){
        clearTimeout(method.tId);
        method.tId=setTimeout(function(){
            method.call(context);
        },500);
    }

Debounce(function(){
//获取流程
},window)
 

  当然,这样也还是存在一个问题,极端情况下,如果事件每隔250ms都被触发一次的话,那么事件就一直在创建--取消的过程,而没有事件真正的执行.

  面对这种情况,我们可以这样处理 (节流 throttle)

  

function throttle(window,call) {

    if(window.tId&&window.tId>0){
        return;

    }else{
        window.tId=setTimeout(function(){
            window.tId=0;
        },500);
    }
    call()
}
 

这样的话 在一定时间内,只允许事件执行一次 ,其它的响应就被抛弃

原文地址:https://www.cnblogs.com/luoyeluoy/p/7625777.html