react 의 떨 림 방지 와 절 류 는 큰 사람 이 포장 하 는 방법 을 사용 하면 시원 합 니 다. - 우리 같이 소스 코드 를 읽 습 니 다.
                                            
 19533 단어  리 액 트 세트
                    
큰 놈 의 바퀴 를 쓰 고 싶 지 않 으 면 직접 써 도 됩 니 다. 이 블 로 그 를 보 세 요. 자 바스 크 립 트 떨 림 방지 와 절 류 – 바퀴 를 만 드 는 것 은 향 기 롭 지 않 습 니까?
사내 의 바퀴 는 두 걸음 이면 사용 할 수 있다.
import React, { Component } from 'react';
import { throttle, debounce } from 'throttle-debounce';//1.  throttle
export default class Children extends Component {
	constructor(props) {
    super(props);
    /**
     * 2.                   
     * @param {number} 2000      
     */
     	this.onClick = throttle(2000, this.onClick);
		this.state = {
		}
	}
	render() {
		return (
			<div>
				<button onClick={this.onClick}>  </button>
			</div>
		)
	}
	onClick = (e) => {
		console.log('e', e);
	}
}
  위 는 react 가 큰 사내 패 키 징 을 개발 하 는 방법 으로 사용 하기에 매우 편리 합 니 다. 두 걸음 만 있 으 면 됩 니 다.
throttle 공부 하 다
그 다음 에 에 리 보 디 는 소스 코드 가 어떻게 실현 되 는 지 보 러 가자. 보고 나 면 우리 스스로 도 바퀴 를 만 들 수 있다.
위의 도입 방법 은
react16.8 버 전 이 고 저 버 전 16.3 은 인용 방법 을 수정 했다.import throttle from 'lodash/throttle'; 
this.onClick = throttle(this.onClick, 2000);
  그러나 이 기능 은 아래로 호 환 되 며, 오래된 방법 은 새 버 전에 서도 사용 할 수 있다.
다음은 새로운 버 전 소스 코드 를 바탕 으로 분석 하 겠 습 니 다.
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
  위의 두 줄 은 엄격 한 모델 을 사용한다.
내 보 내기 모듈 을 설정 하 는 방식 (이것 은 잘 모 르 겠 습 니 다. 내 보 내기 방식 을 설정 하고 일부 자 료 를 찾 아 보 았 지만 아직 결과 가 나 오지 않 았 습 니 다. 제 가 알 아 보고 보충 하 겠 습 니 다)
알 겠 습 니 다. 다시 보충 하 겠 습 니 다. 이 소스 코드 가 있 는 파일 은
index.cjs.js 즉, babel 을 통 해 전 환 된 commonJS 코드 입 니 다.모듈 의 출력 대상 추가
__esModule 는 바벨 의 요구 에 부합 하지 않 는 CommonJS 모듈 을 요구 에 부합 하 는 모듈 로 변환 하기 위 한 것 이라는 점 require 에서 드러난다.모듈 을 불 러 온 후에 불 러 온 모듈 이 하나의 __esModule 속성 을 가지 고 있 는 것 을 발견 하면 Babel 은 이 모듈 이 틀림없이 바 뀌 었 다 는 것 을 알 게 될 것 입 니 다. 그러면 Babel 은 불 러 온 모듈 에서 안심 하고 exports.default 이 내 보 낸 대상, 즉 ES6 에 규정된 기본 내 보 내기 대상 을 호출 할 수 있 습 니 다. 그래서 이 모듈 은 CommonJS 기준 에 도 부합 합 니 다.Babel 의 ES6 모듈 화 수요 에 도 부합 합 니 다.그러나 __esModule 이 존재 하지 않 는 다 면 괜 찮 습 니 다. Babel 은 감지 되 지 않 는 __esModule 모듈 을 불 러 왔 을 때 이 모듈 이 CommonJS 기준 에 부합 되 지만 제3자 모듈 일 수 있 습 니 다. Babel 은 이 모듈 을 바 꾼 적 이 없습니다. 나중에 직접 사용 하면 exports.default 오류 가 발생 할 수 있 습 니 다. 그래서 지금 은 default 속성 을 추가 합 니 다.차라리 default 속성 이 자신 을 가리 키 게 하면 좋 겠 다. 그러면 앞으로 실수 하지 않 을 것 이다.이 해석 은 바벨 이 ES6 module 로 전환 하 는 원 리 를 분석 한 데 서 비롯 된 것 으로, 여러 선배 님 들 의 도움 에 도 감 사 드 립 니 다.       ,         ,  “resize”,“scroll”           
 /**
 * @param  {Number}    delay         
 * @param  {Boolean}   [noTrailing] 
 * @param  {Function}  callback       
 * @param  {Boolean}   [debounceMode] 
 * @return {Function}  A new, throttled, function.
 */
delay :         number              0       ,       ,  100 250(    )   。
[noTrailing] :             []      ,   false,     true,       ‘delay’  ,  
                                  ,  noTrailing   false     ,                ,
                                     ( “delay”          ,       )
                               
callback :                    “delay”        ,this              ,       
                                 “callBack”
                               
[debounceMode]:               “debounceMode”    true,   “delay”     “clear”  ,  
                               “debounceMode”      false,   “delay”     “callBack”  。
                               
   :                            
function throttle (delay, noTrailing, callback, debounceMode) {
  /*
   * After wrapper has stopped being called, this timeout ensures that
   * `callback` is executed at the proper times in `throttle` and `end`
   * debounce modes.
   */
            ,            ,             
   
  var timeoutID;
  var cancelled = false; //           
  
  var lastExec = 0; //          
  
  function clearExistingTimeout() {
    if (timeoutID) {
      clearTimeout(timeoutID);
    }
  } //      exec  
  
  function cancel() {
    clearExistingTimeout();
    cancelled = true;
  } //       ,    
  if (typeof noTrailing !== 'boolean') {
    debounceMode = callback;
    callback = noTrailing;
    noTrailing = undefined;
  }
  
  //            /    ,                 
  function wrapper() {
    var self = this;
    var elapsed = Date.now() - lastExec;
    var args = arguments;
    if (cancelled) {
      return;
    } //     ,  lastExec   
    function exec() {
      lastExec = Date.now();
      callback.apply(self, args);
    }
	//               true,                     
    function clear() {
      timeoutID = undefined;
    }
    if (debounceMode && !timeoutID) {
      //       ,      ,    
      exec();
    }
    clearExistingTimeout();
    if (debounceMode === undefined && elapsed > delay) {
      //      ,        ,      
      exec();
    } else if (noTrailing !== true) {
      /*
	   *         ,         ,                  
       *          ,   ’delay‘     ’clear‘
       *         false,   ’delay‘       
	   */
      timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay);
    }
  }
  wrapper.cancel = cancel; //        
  return wrapper;
}
/**
 *
 * @param  {Number}   delay         
 * @param  {Boolean}  [atBegin]                                   
 * @param  {Function} callback      
 * @return {Function} A new, debounced function.
 */
       ,       ,         ,                 
delay:                         ,      ,    100 250(    )    
atBegin:              ,  false,  atBegin false     ,             
                          “delay”      ,  atBegin true,              
                           ( “delay”             ,     )
                        
callback:                       。“this”                     
                            “callback”。
function debounce (delay, atBegin, callback) {
  return callback === undefined ? throttle(delay, atBegin, false) : throttle(delay, callback, atBegin !== false);
}
exports.throttle = throttle;
exports.debounce = debounce;
  본 고 는 제 가 처음으로 진지 하고 꼼꼼 하 게 알 아 본 것 입 니 다. 모든 줄 의 소스 코드 를 연구 하고 자신 이 만 든 바퀴 로 큰 사람 을 비교 하 는 것 입 니 다. 배 워 야 할 것 이 많 습 니 다. 글 에서 해석 이 제대로 되 지 않 고 잘못된 부분 을 설명 하 는 경우 가 많 습 니 다. 선배 님 들 께 서 많이 지적 해 주 셨 으 면 좋 겠 습 니 다.