JS 떨 림 방지 와 절 류 실현

3453 단어
1. 떨 림 방지 와 절 류 는 무엇 입 니까? 예 를 들 어 검색 상자, 사용자 가 입력 할 때 change 이 벤트 를 사용 하여 검색 을 호출 합 니 다. 사용자 가 매번 입력 할 때마다 검색 을 한다 면 얼마나 큰 서버 자원 을 소모 해 야 합 니까? 서버 자원 이 강하 더 라 도 이렇게 놀 지 않 습 니 다.
1. 떨 림 방지 - debounce 의 해결 방안 중 하 나 는 사용자 가 입력 을 중단 한 후에 500 ms 가 지 연 될 때마다 이때 의 String 을 검색 하 는 것 입 니 다. 이것 이 떨 림 방지 입 니 다.  * 원리: 몇 개의 함 수 를 한 번 으로 호출 하고 주어진 시간 이 지나 면 한 번 만 호출 됩 니 다.  * 코드 구현:
function debounce(fn, delay) {
  //      timer,            
  let timer = null;

  return function() {
    //    ‘this’   ‘arguments’            
    let context = this;
    let args = arguments;
    //           ,     
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  }
}
let flag = 0; //           
//             
function foo() {
  flag++;
  console.log('Number of calls: %d', flag);
}

//   debounce         ,  2      
document.body.addEventListener('scroll', debounce(foo, 2000));

debounce 함수 패 키 징 후 내부 함수 로 돌아 가 이벤트 가 실 행 될 때마다 현재 timer 를 제거 하고 시간 초과 설정 을 다시 설정 합 니 다.이 로 인해 모든 고주파 사건 이 지난번 의 시간 초과 호출 을 취소 하고 사건 처리 프로그램 이 트리거 되 지 못 하 게 됩 니 다. 고주파 사건 이 멈 춰 야 마지막 사건 이 촉발 하 는 시간 초과 호출 이 delay 시간 후에 실 행 될 수 있 습 니 다. 2. 스로틀 의 다른 해결 방안 은 떨 림 방지 보다 느슨 합 니 다. 이때 우 리 는 사용자 의 입력 만 하고 싶 지 않 습 니 다.사용자 에 게 검색 힌트 를 주 는 것 이기 때문에 500 ms 가 지나 면 이 스 트 링 을 한 번 씩 조회 하 는 것 을 제한 합 니 다. 이것 이 바로 절 류 입 니 다.  * 원리: 절 류 함 수 는 사건 의 촉발 이 아무리 빈번 하 더 라 도 규정된 시간 내 에 반드시 진정한 사건 처리 함 수 를 실행 할 것 을 보장 합 니 다.  * 코드 구현 은 두 가지 가 있 는데, 하 나 는 타임 스탬프 이 고, 다른 하 나 는 타이머 이다.  1) 타임 스탬프 구현:
function throttle(func, delay){
  let prev = Date.now();
  return function(){
    const context = this;
    const args    = arguments;
    const now     = Date.now();
    if(now - prev >= delay){
      func.apply(context, args);
      prev = Date.now();
    }
  }
}

고주파 이벤트 가 실 행 될 때 첫 번 째 는 바로 실 행 될 것 입 니 다.마지막 사건 이 촉발 되면 사건 은 더 이상 집행 되 지 않 는 다.
2) 타이머 구현:  이 벤트 를 촉발 할 때, 우 리 는 타 이 머 를 설정 하고 이 벤트 를 촉발 할 때 타 이 머 가 존재 하면 실행 하지 않 습 니 다.delay 초 후에 타이머 가 실행 함 수 를 실행 하고 타 이 머 를 비우 면 다음 타 이 머 를 설정 할 수 있 습 니 다.
fucntion throttle(func, delay){
  let timer = null;

  return funtion(){
    let context = this;
    let args    = arguments;
    if(!timer){
      timer = setTimeout(function(){
        func.apply(context, args);
        timer = null;
      }, delay);
    }
  }
}

첫 번 째 트리거 이 벤트 는 함 수 를 즉시 실행 하지 않 고 delay 초 후에 실 행 됩 니 다.  이후 이벤트 가 계속 발생 하면 delay 초 에 한 번 씩 실 행 됩 니 다.  마지막 으로 트리거 를 멈 춘 후 타이머 의 delay 지연 으로 함수 가 실 행 될 수 있 습 니 다.
3) 타임 스탬프 와 타 이 머 를 종합 적 으로 사용 하여 이벤트 트리거 가 완료 되 었 을 때 즉시 실행 하고 트리거 가 완료 되 었 을 때 한 번 더 실행 할 수 있 는 절 류 함수
function throttle(func, delay){
  let timer = null;
  let startTime = Date.now();

  return function(){
    let curTime = Date.now();
    let remaining = delay - (curTime - startTime);
    const context = this;
    const args = arguments;

    clearTimeout(timer);
    if(remaining <= 0){
      func.apply(context,args);
      startTime = Date.now();
    }else{
      timer = setTimeout(func, remaining);
    }
  }
}

모든 delay 시간 에 한 번 씩 함 수 를 실행 해 야 하기 때문에 절 류 함수 내부 에서 시작 시간, 현재 시간 과 delay 를 사용 하여 remaining 을 계산 합 니 다. remaining < = 0 시 에 이 실행 함 수 를 표시 합 니 다. 시간 이 되 지 않 았 다 면 remaining 시간 후에 트리거 하도록 설정 합 니 다.물론 remaining 기간 에 또 한 번 사건 이 발생 하면 현재 타 이 머 를 취소 하고 remaining 을 다시 계산 하여 현재 상 태 를 판단 합 니 다.원문:https://blog.csdn.net/sml115/article/details/81280101

좋은 웹페이지 즐겨찾기