JavaScript 50問――真剣に雑談して、震えと節流を流します.

2783 ワード

前言
面接であれ、ブラウザの最適化を議論する過程であれ、ディザの除去と節流の問題に関わる.総じて、この2つは、イベントのトリガ周波数を制限する方法である.異なるのは、イベントトリガの時間間隔を指定します.ディザリングを行うとイベントがトリガされない時間間隔を指定します.その結果から、節流は時間処理の感度を低下させた.そして、指定されたイベント間隔を超えたら、一斉に送信するように、トリガーイベントから最初にセットされます.ますますめまいがします.直接コードをつけます.HTML.
ここにはユーザ検索用のinputタグがあります.inputイベントがトリガする処理関数fatchがあります.このfatchはinputのvalue値に基づいてバックグラウンドに連想語を要求します.上のコードの考えは大丈夫ですが、トリガ制限をしないと大量のhttp要求が発生する可能性があります.これらの要求の中には多くの意味があります.次に、私は節流と手を振ってこの問題を解決します.(普通はinputに対して、手ぶれで解決します.ここではコードの説明がしやすいだけです.)
流れをよくする
function jieliu (func, time){//func     , time     
  let lastRun = null
  
  return function(){
    const now = new Date()
    if(now - lastRun > time){
      func(...arguments)
      lastRun = now
    }
  }
}


const listener = jieliu(function(value){//    ,      
  console.log(value)
}, 1000)

const input = document.querySelector("input")
//    
input.addEventListener("input", function(event){
     listener(event.target.value)
})
以上は比較的簡単な節流実現及び基本的な呼び出し方式である.クローズドを使うのは、一回ごとに実行されるlastRunを保存するためです.要求周波数を制限する需要が基本的に実現されたが、最後のトリガは無視された.改善は以下の通りです
function jieliu (func, time){//       >time     
  let lastRun = null
  let timeout = undefined
  return function(){
    const self = this; 
    const now = new Date()
    if(now - lastRun > time){
      if(timeout){
        clearTimeout(timeout)
        timeout = undefined
      }
      func.apply(self, arguments)
      lastRun = now
    }
    else{
      if(!timeout){
        timeout = setTimeout(func.apply(self, arguments), time)
      }
    }
  }
}
timeoutに参加して、最後の要求かどうかを判断します.
ディザリング
function qudou(func, time){
  let timeout = undefined
  
  return function(){
    const argu = arguments
    const self = this

    if(timeout){
      clearTimeout(timeout)
      timeout = undefined
    }else{
        timeout = setTimeout(func.apply(this, arguments), time)
    }
  }
}
以上の簡単なディザリングを実現しました.同様に、最後のイベントは処理関数をトリガすることができません.
改善は以下の通りです
function qudou(func, time){//    time      ,  func  
  let timeout = undefined;
  let lastRun = null
  return function(){
    const self = this
    const now = new Date()
    if(now - lastRun > time){
      func.apply(self, arguments)
    }
    else {
      if(!timeout){
        timeout = setTimeout(func.apply(self, arguments), time)
      }
      else {
        clearTimeout(timeout)
        timeout = undefined
      }
    }
    lastRun = new Date()
  }
}
締め括りをつける
全体を通して書いて、節流の主要な実現方法はやはり「now」と「lastRun」の時間差を比較することによって、処理関数の呼び出し回数を減少させます.また、手ぶれ防止は、処理関数の呼び出しタイミングをsettimeoutにより遅らせ、さらに複数回トリガした結果をまとめて処理関数を呼び出す.
後記
節流とディザリングはやはり大きく違っています.多くの人が私を含めて混ぜやすいです.より良い解決策や議論が必要なところがあれば、積極的にコメントしてください.