js debounce 함수 에 대한 약간의 사고

4711 단어
나 는 비교적 멍청 한 사람 이다. 어떤 사람들 은 논리 적 으로 큰 모퉁이 를 돌기 가 쉽 지 않 아서, 일단 너무 크게 돌 면 차 에 부 딪 히 기 쉬 워 서 이해 할 수 없다.오늘 저 는 input [type = password] 를 하 는 과정 에서 사용자 가 입력 한 비밀 번 호 를 포맷 검사 해 야 합 니 다. 그러나 저 는 사용자 가 입력 할 때마다 한 번 검사 하고 싶 지 않 습 니 다. 프로그램 에 사용자 의 입력 이 1000 밀리초 동안 멈 춘 후에 다시 검사 하 기 를 바 랍 니 다.그래서 스스로 해 보고 싶 었 다.


먼저 생각 나 는 것 은 lodash 에 있 는 debounce 함수 입 니 다. 그래서 있 습 니 다.
import { debounce } from 'lodash'
...
inputHandler(event){
      let password = event.target.value
      debounce(()=>{
          let reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\S]{8,32}$/;
          if (reg.test(password) !== true) {
            console.log(11111)
          }
      }, 1000)
},

그 결과 console.log(11111) 전혀 집행 되 지 않 은 것 으로 나 타 났 다.어 쩔 수 없 이 동료 에 게 엘리베이터 의 비유, 고급 함수, 너 는 input Handler 를 debounce 에 넣 어야 한다. 나 는 비교적 멍청 하기 때문에 정말 알 아 듣 지 못 했다.어 쩔 수 없 이 집에 가서 다시 생각 하고 본원 을 거 슬러 올 라 가 는 것 이 나 를 좀 편 하 게 해 주 었 다.
앞에서 언급 한 바 와 같이 debounce 를 하 는 주요 의 도 는 사용자 가 1 초 간격 으로 입력 한 후에 비밀번호 형식 을 검사 하 게 하려 는 것 이다. 1 조건 반사 적 으로 생각 하 는 것 은 다음 과 같다.
setTimeout(()=>{
  console.log('    ')
},1000)

그 깊 은 것들 을 떠 나 서, 우 리 는 먼저 이 코드 를 inputHandler 에 추가 합 니 다.
inputHandler(event){
      let password = event.target.value
      setTimeout(()=>{
        let reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\S]{8,32}$/;
        if (reg.test(password) !== true) {
          console.log(11111)
        }
      },1000)
},

이때 input 에 입력 하 니 console.log(11111) 실행 되 었 습 니 다. 만리장성 의 첫 걸음 입 니 다.다음 문 제 는 여러분 도 아시 다시 피 제 가 input 에 3 자 모 를 입력 하면 11111 콘 솔 에 3 번, 6 자 모 를 입력 하면 6 번, 이때 저희 가 원 하 는 debounce 의 목적 을 달성 하지 못 했 습 니 다.이 는 input 에 알파벳 을 입력 할 때마다 inputHandler 한 번 씩 실행 되 기 때문이다.6 자 모 를 입력 하면 setTimeout 6 회 실행 되 기 때문에 콘 솔 에 6 개 11111 가 나타난다.setTimeout 이 한 번 만 실 행 했 으 면 좋 겠 다 고 직관 적 으로 생각 합 니 다.따라서 논 리 는 1 초 안에 inputHandler 를 다시 실행 하면 지난번 setTimeout 을 취소 하고 새로운 setTimeout 을 다시 실행 하 는 것 으로 바 뀌 었 다.마침 우 리 는 setTimeout 을 취소 하 는 방법, 즉 clearTimeout 을 알 고 있다.MDN 문 서 를 읽 으 면 다음 을 알 수 있 습 니 다.
setTimeout 반환 값 timeoutID 은 타이머 의 번 호 를 나타 내 는 정수 입 니 다.이 값 은 이 시간 을 취소 하기 위해 clearTimeout() 에 전달 할 수 있다.
그래서 우 리 는 clearTimeout (setTimeout 의 반환 값) 만 있 으 면 이 시간 을 취소 할 수 있다 는 것 을 알 고 있다.저 희 는 현재 setTimeout 의 번 호 를 기록 하 는 변 수 를 추가 하여 적당 한 시기 에 clearTimeout (timeoutID) 을 실행 할 수 있 도록 합 니 다.
inputHandler(event){
      let password = event.target.value
      let timeoutID = setTimeout(()=>{
        let reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\S]{8,32}$/;
        if (reg.test(password) !== true) {
          console.log(11111)
        }
      },1000)
},

합 리 적 인 논리 적 추 리 를 통 해 우 리 는 반드시 inputHandler 실 행 될 때 지난번 setTimeout 을 비 워 야 합 니 다. 우 리 는 clearTimeout (timeoutID) 을 코드 에 추가 합 니 다.
inputHandler(event){
      clearTimeout(timeoutID)
      let password = event.target.value
      let timeoutID = setTimeout(()=>{
        let reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\S]{8,32}$/;
        if (reg.test(password) !== true) {
          console.log(11111)
        }
      },1000)
},

그러나 문제 가 발생 했 습 니 다. 이 때 timeoutID 가 설명 되 지 않 았 기 때문에 clearTimeout 은 무효 입 니 다.더구나 매번 타임 아웃 ID 를 다시 밝 혔 다 면 클 리 어 타임 아웃 은 현재 의 setTimeout 이다.그럼 지난번 timeoutID 는 어떻게 비 웁 니까?전역 변 수 를 사용 해 야 합 니 다:
let timeoutID
inputHandler(event){
      clearTimeout(timeoutID)
      let password = event.target.value
      timeoutID = setTimeout(()=>{
        let reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\S]{8,32}$/;
        if (reg.test(password) !== true) {
          console.log(11111)
        }
      },1000)
},

페이지 를 불 러 온 후 전역 변수 timeoutID 는 메모리 에 항상 존재 합 니 다. 처음으로 input 에 알파벳 을 입력 했 을 때 timeoutID 가 할당 되 지 않 았 기 때문에 첫 번 째 clearTimeout (timeoutID) 은 실 행 했 지만 의미 가 없습니다.let password = event.target.value 이후 코드 는 setTimeout 의 반환 값 을 timeoutID 에 할당 합 니 다.우리 가 1 초 안에 두 번 째 input 에 알파벳 을 입력 하면 두 번 째 실행 clearTimeout(timeoutID) 을 할 때 지 워 진 timeoutID 는 지난번 setTimeout 의 반환 값 입 니 다.코드 가 계속 실 행 됨 에 따라 두 번 째 setTimeout 반환 값 을 timeoutID 에 부 여 했 습 니 다.이때 input 입력 을 하지 않 으 면 1 초 후에 console.log(11111) 실 행 됩 니 다.이때 우 리 는 debounce 효 과 를 실현 했다.
최적화 하 다.
기능 이 실현 되 었 지만 추 한 전역 변수 timeoutID 가 있 습 니 다. 코드 를 재 구성 해서 전역 변 수 를 사용 하지 않 을 수 있 습 니까?내 가 생각 한 것 은 초기 화 함수 init () 를 쓰 고 그 안에 timeoutID 를 부여 하 는 것 이다. 페이지 를 불 러 올 때 init () 를 호출 하면 timeoutID 를 전역 이 라 고 부른다.
init(){
  let timeoutID
}

미 완성 계속.

좋은 웹페이지 즐겨찾기