JavaScriptにおける手ぶれ防止と節流

11908 ワード

JavaScriptの中の手ぶれ防止と節流というのは、setTimeoutsetIntervalの使い方です.
  • 手ぶれ防止
  • ユーザが高周波でイベントをトリガする時、私達は関数を直ちに実行させるのではなく、次の私達が規定する時間にユーザがこのイベントを実行し続けることはないかを確認します.
      ?    :     
    
    下には偽コードを書いています.私は書きたくないので、コピーしました.
    //         
    var debounce = (fn, wait, immediate = false) => {
    	let timer, startTimeStamp = 0;
    	let context, args;
     
    	let run = (timerInterval)=>{
    		timer = setTimeout(()=>{
    			let now = (new Date()).getTime();
    			let interval = now - startTimeStamp
    			// the timer start time has been reset,so the interval is less than timerInterval
    			if(interval < timerInterval){ 
    				console.log('debounce reset', timerInterval-interval);
    				startTimeStamp = now;
    				run(timerInterval - interval);  // reset timer for left time 
    			} else { //   wait       
    				if(!immediate){
    					fn.apply(context, args);
    				}
    				clearTimeout(timer);
    				timer = null;
    			}
    			
    		}, timerInterval);
    	}
     
    	return function(){
    		context = this;
    		args = arguments;
    		let now = (new Date()).getTime();
    		startTimeStamp = now; // set timer start time
     
    		if(!timer){
    			console.log('debounce set',wait);
    			if(immediate) {
    				fn.apply(context, args);
    			}
    			run(wait);    // last timer alreay executed, set a new timer
    		}	
    	}
    }
    
  • 節流は何が節流ですか?規定の時間内に一回だけ実行します.
    意外とは言えませんが、この方法も赋価で贴られています.
    //     
    var throttling = (fn, wait, immediate) => {
    	let timer, timeStamp = 0;
    	let context, args;
     
    	let run = () => {
    		timer = setTimeout(()=>{
    			if(!immediate){
    				fn.apply(context,args);
    			}
    			clearTimeout(timer);
    			timer = null;
    		}, wait);
    	}
     
    	return function () {
    		context = this;
    		args = arguments;
    		if(!timer){
    			console.log("throttle, set");
    			if(immediate){
    				fn.apply(context,args);
    			}
    			run();
    		} else {
    			console.log("throttle, ignore");
    		}
    	}
     
    }
    
    具体的な実施形態は、lodashにおける実装を参照することができる.