JavaScript先端性能最適化イベントの手ぶれ防止

6237 ワード

定義:トリガイベント後、所定時間内にコールバック関数は一回しか実行できません.規定時間内にイベントがトリガされた場合、再び規定のタイミングを開始し、新しいイベントの時間を基準として、n秒後に実行します.
アプリケーションシーン:
  • 項の検索を入力する時、ユーザは絶えず値を入力する時、手ぶれを防ぎながら資源を要求することを節約します.
  • ボタンをクリックしてください.例えば、いいね.コレクション
  • .
    手ぶれ防止には二つの実現方法があります.
  • は、直ちに実行されない:大体ステップ関数呼び出し->>遅延->は、コールバック関数を実行し、遅延時に関数がトリガされると、再度遅延動作を行い、遅延終了後にコールバック関数
  • を実行する.
  • は直ちに実行します.大体ステップ関数コール->はコールバック関数->遅延を実行します.遅延時に関数がトリガされると、再度遅延動作を行います.遅延終了後はコールバック関数
  • は実行されません.
    直ちに実行しない
    function debounce(fun,wait=300){
      let timer = null;
        return function () {
            let self = this,
                args = arguments;
            timer && clearTimeout(timer);
            timer = setTimeout(function () {
                method.apply(self,args);
            },delay);
        }
    }
    
    直ちに実行する
     function debounce(func,wait,immediate){
                let timeout;
                return function(){
                    let context = this;
                    let args = arguments;
    
                    if(timeout){
                        clearTimeout(timeout);
                    }
                    if(immediate){
                        //        ,    
                        timeout = setTimeout(function(){
                            timeout = null;
                        },wait);
                        if (!timeout) func.apply(context, args)
                    }else{
                        timeout = setTimeout(function(){
                            func.apply(context,args);
                        },wait);
                    }
                }
            }
    
    拡張
    私たちが入ってきたfuncは戻り値があると仮定して、関数の実行結果を返します.ただし、immediateがfalseである場合、setTimeoutを使って、func.applyの戻り値を変数に割り当てます.最後にreturnすると、値は常にundefinedです.ですから、私たちはimmediateがtrueの時だけ関数の実行結果を返します.
     function debounce(func,wait,immediate){
                let timeout,result;
                return function(){
                    let context = this;
                    let args = arguments;
    
                    if(timeout){
                        clearTimeout(timeout);
                    }
                    if(immediate){
                        //        ,    
                        timeout = setTimeout(function(){
                            timeout = null;
                        },wait);
                        if (!timeout) result = func.apply(context, args);
                    }else{
                        timeout = setTimeout(function(){
                            func.apply(context,args);
                        },wait);
                    }
                    return result;
                }
            }
    
    最後に、私たちはもう一つの小さな需要を考えます.debounce関数をキャンセルしたいです.例えば、debounceの時間間隔は10秒です.immediateはtrueです.これでは、8秒以上待つしかないです.今はボタンがほしいです.クリックした後、手ぶれを防ぐために、再度触発したら、すぐに実行できます.
     function debounce(func,wait,immediate){
                let timeout,result;
                let debounced = function(){
                    let context = this;
                    let args = arguments;
    
                    if(timeout){
                        clearTimeout(timeout);
                    }
                    if(immediate){
                        //        ,    
                        timeout = setTimeout(function(){
                            timeout = null;
                        },wait);
                        if (!timeout) result = func.apply(context, args);
                    }else{
                        timeout = setTimeout(function(){
                            func.apply(context,args);
                        },wait);
                    }
                    return result;
                }
                
               debounced.cancel = function(){
                   clearTimeout(timeout);
                    timeout = null;
               } 
            }