当前位置: 首页 > Web前端 > JavaScript

JavaScript函数防抖、函数节流

时间:2023-03-27 12:31:21 JavaScript

1銆佸墠瑷€鐩镐俊鏃犺鏄湪瀹為檯搴旂敤鍦烘櫙杩樻槸闈㈣瘯涓紝閮戒細缁忓父閬囧埌鍑芥暟闃叉姈銆佸嚱鏁拌妭娴佺瓑闂锛屼笅闈㈠氨鏉ヨ璇村惂銆傚厛鏀惧嚭涓€涓緥瀛愶細importReact,{useEffect,useRef}from'react'importdebouncefrom'../../utils/debounce'importthrottlefrom'../../utils/throttle'importstylefrom'./index.scss'瀵煎嚭榛樿鍑芥暟Demo(props){constinputElem1=useRef()constinputElem2=useRef()constinputElem3=useRef()useEffect(()=>{inputElem1.current.addEventListener('keyup',request)inputElem2.current.addEventListener('keyup',debounce(request,1000))inputElem3.current.addEventListener('keyup',throttle(request,3000))},[])functionrequest(event){const{value}=event.targetconsole.log(`Httprequest:${value}.`)}return(鏅€氳緭鍏ユ锛?/label>

闃叉姈杈撳叆妗嗭細
娌归棬杈撳叆妗嗭細
label>
)}涓婇潰Demo涓彧鏈変笁涓緭鍏ユ锛岄潪甯哥畝鍗曘€傛垜缁欐瘡涓緭鍏ユ閮界粦瀹氫簡涓€涓猭eyup閿洏浜嬩欢锛岃繖涓簨浠剁殑鎵ц浼氬彂璧蜂竴娆$綉缁滆姹傦紙涓轰簡绠€鍗曪紝杩欓噷鍙槸鎵撳嵃涓€涓嬶級锛岀浉搴旂殑闃叉姈鍜岃妭娴佽緭鍏ユ杩涜鐩稿簲鐨勫鐞嗐€?.鍔熻兘闃叉姈锛坉ebounce锛夊鏋滄垜浠湪鏅€氱殑杈撳叆妗嗗揩閫熻緭鍏?2345锛屼粠鎺у埗鍙扮殑鎵撳嵃缁撴灉鍙互鐪嬪嚭浼氬彂璧?娆$綉缁滆姹傦紙鍋囪鎴戜滑鏄竴涓畝鍗曠殑鎼滅储寮曟搸锛夈€備笉鐭ラ亾鐢ㄤ粈涔堟埅灞?褰曞睆杞欢鍙互鐢熸垚GIF鍔ㄥ浘銆傛湁绌哄啀鐮旂┒涓€涓嬨€傘€傘€傝€冭檻鍒板疄闄呭満鏅紝濡傛灉姣忚緭鍏ヤ竴涓瓧绗︼紝灏辩珛鍗冲彂璧风綉缁滆姹傚幓鑾峰彇缁撴灉锛屼細闈炲父褰卞搷浣撻獙銆?鍋囪鎴戜滑闄愬埗涓猴細鐢ㄦ埛鍋滄杈撳叆鍚?绉掑彂璧风綉缁滆姹傘€傝杈惧埌杩欐牱鐨勮姹傦紝鎴戜滑鍙渶瑕佷娇鐢ㄥ姛鑳介槻鎶栧嵆鍙€?.1浠€涔堟槸鍔熻兘闃叉姈锛熸蹇碉細鍦ㄤ竴瀹氱殑鏃堕棿闂撮殧鍐咃紝浜嬩欢澶勭悊鍑芥暟鍙細鎵ц涓€娆°€傚鏋滃湪璇ユ椂闂撮棿闅斿唴閲嶆柊瑙﹀彂锛堝娆★級锛屽垯璁℃椂鍣ㄥ皢閲嶇疆銆傚浣曠悊瑙o紵鍋囪鐢ㄦ埛鍦ㄨ緭鍏ュ瓧姣峚鍚庡仠姝㈣緭鍏ワ紝閭d箞缃戠粶璇锋眰浼氬湪鍋滄杈撳叆鎿嶄綔鍚?s鍙戣捣銆傝繖寰堝鏄撶悊瑙c€傚鏋滅敤鎴风户缁緭鍏ュ瓧姣峛锛屼粬鑻ユ湁鎵€鎬濆湴鍋滈】浜嗕竴浼氬効锛堣繖涓椂闂村湪1s浠ュ唴锛屽亣璁炬槸800ms锛夛紝鐒跺悗杈撳叆瀛楁瘝c锛岀劧鍚庡仠姝㈣緭鍏ャ€傜綉缁滆姹傚皢鍦ㄨ緭鍏ュ瓧姣峜鍚?s鍙戣捣锛岃€屼笉鏄緭鍏ュ瓧姣峛鍚?s鍙戣捣銆傚洜涓哄嚱鏁癲ebounce浼氬湪杈撳叆c鍚庨噸鏂拌鏃躲€?.2鍑芥暟闃叉姈瀹炵幇debounce(func,wait)瀹炵幇鎬濊矾锛氶鍏堟帴鏀朵袱涓弬鏁癴unc锛堣闃叉姈鐨勫嚱鏁帮紝涓€鑸槸浜嬩欢鍥炶皟鍑芥暟锛夊拰wait锛堥渶瑕佸欢鏃剁殑鏃堕棿闂撮殧锛屽崟浣嶆绉掞級).鐒跺悗鍦╯etTimeout涓墽琛宖unc锛宻etTimeout鐨勫欢杩熸椂闂翠负wait銆傚浜庨噸瀹氭椂锛屽彲浠ュ湪姣忔瑙﹀彂鏃舵墽琛宑learTimeout銆傞渶瑕佹敞鎰忕殑鏄痜unc鐨勬墽琛屼笂涓嬫枃锛坱his锛夊強鍏跺叆鍙傘€?/debounce.jsfunctiondebounce(func,wait){lettimerIdreturnfunction(){//褰撳墠杩愯涓婁笅鏂囷紝浠ュ強瀹為檯鍙傛暟constcontext=thisconstargs=arguments//retime锛堝叧閿槸杩欎竴姝ワ級//鍦―uring绛夊緟鏃堕棿锛屽鏋滃啀娆¤Е鍙戯紝鍒欐竻绌篶learTiemout锛岃揪鍒伴噸鏂拌鏃剁殑鏁堟灉瀹炲弬func鎸囧悜window瀵硅薄锛屽弬鏁颁负绌篺unc.apply(context,args)},wait)}}鍊熷姪ES6鐨凴est鍙傛暟鍜岀澶村嚱鏁拌娉曪紝绠€鍖栦竴涓嬶細functiondebounce(func,wait){lettimerIdreturnfunction(...args){if(timerId)clearTimeout(timerId)timerId=setTimeout(()=>{func.apply(this,args)},wait)}}鍦ㄥ搴旂殑杈撳叆妗嗕腑杈撳叆12345鍙嶈繃鏉ワ紝瀵规瘮涓€涓嬮槻鎶栧墠鍚庣殑缁撴灉锛氫袱娆℃墦瀛楅€熷害宸笉澶氾紝姣忔鎵撳瓧鐨勬椂闂撮棿闅攃haracter灏忎簬1s锛堝彲浠ヨ皟鏁村欢鏃舵墽琛屾椂闂达紝鏂逛究瀵规瘮锛夈€?/鏅€氳緭鍏ユinputElem1.current.addEventListener('keyup',request)//闃叉姈杈撳叆妗唅nputElem2.current.addEventListener('keyup',debounce(request,1000))鍜屼笂闈㈡病鏈夐槻鎶栧鐞嗙殑姣旇緝鍜岄槻鎶栧鐞嗙粨鏋滃彲浠ョ湅鍒帮紝鍓嶈€呮瘡鏁蹭竴涓瓧绗﹀氨浼氭墽琛屼竴娆″洖璋冨嚱鏁帮紝鑰屽悗鑰呭垯鏄湪杈撳叆鐨凬姣锛堝嵆绛夊緟寤惰繜鏃堕棿锛夊悗鎵嶆墽琛屽洖璋冨嚱鏁版渶鍚庤Е鍙戙€傝繕鏈変竴涓€滅珛鍗虫墽琛屸€濆姛鑳介槻鎶栵細鍖哄埆鍦ㄤ簬绗竴娆¤Е鍙戞椂鏄惁绔嬪嵆鎵ц鍥炶皟鍑芥暟銆傜粨鍚堜笂闈㈢殑鈥滈潪绔嬪嵆鎵ц鈥濋槻鎶栵紝瀹屾暣鐨勬柟娉曞涓嬶細/***鍑芥暟闃叉姈*@param{Function}func瑕侀槻鎶栫殑鍑芥暟*@param{number}wait闇€瑕佸欢杩熺殑姣鏁?@param{boolean}immdeiate鏄惁绔嬪嵆鎵ц*@returns{Function}杩斿洖涓€涓柊鐨勫幓鎶栧姩锛堥槻鎶栵級鍔熻兘*/functiondebounce(func,wait=0,immdeiate=false){璁﹖imerId杩斿洖鍑芥暟(...args){if(timerId)clearTimeout(timerId)if(immdeiate&&!timerId){func.apply(this,args)}timerId=setTimeout(()=>{func.apply(this,args)},wait)}}褰撴垜浠妸瀹冩敼鎴愶細inputElem2.current.addEventListener('keyup',debounce(request,1000,true))浠庝笅闈㈢殑缁撴灉鍙互鐪嬪嚭锛屽綋鎴戣緭鍏?2345鏃堕槻鎶栬緭鍏ユ锛屽綋鎴戣緭鍏?涓綉缁滆姹傛椂锛屽畠浼氱珛鍗冲惎鍔紝鐢变簬杈撳叆姣忎釜瀛楃鐨勬椂闂撮棿闅斿湪1s浠ュ唴锛屾墍浠ュ畠鍙細鍦ㄦ渶鍚庝竴涓?s鍚庡彂璧风綉缁滆姹傛墦瀛椼€?.functionthrottle鐨勬蹇碉細涓€涓猣unction鍦ㄤ竴瀹氱殑鏃堕棿闂撮殧鍐呭彧浼氳瑙﹀彂涓€娆°€傚鏋滃湪姝ゆ椂闂撮棿闅斿唴澶氭瑙﹀彂璇ュ姛鑳斤紝鍒欏彧鏈夌涓€娆$敓鏁堛€?.1鍑芥暟鑺傛祦鐨勫疄鐜癴unctionthrottle(func,wait){//璁板綍func鐨勬渶鍚庝竴娆℃墽琛屾椂闂磍etprev=0returnfunction(...args){//褰撳墠瑙﹀彂鏃堕棿锛堟椂闂存埑锛塩onstnow=Number(newDate())//+newDate()//鍗曚綅鏃堕棿鍐呭彧浼氭墽琛屼竴娆f(now>=prev+wait){//褰揻unc鎸夋潯浠舵墽琛屾椂锛岄渶瑕佹洿鏂皃rev鏃堕棿prev=nowfunc.apply(this,args)}}}3.2鍑芥暟鑺傛祦浼樺寲涓婇潰鐨勮妭娴佹柟寮忔湁闂銆傚亣璁捐妭娴佹帶鍒堕棿闅斾负1s锛屽鏋滀笂娆¤Е鍙戞椂闂翠负1.5s锛屽垯涓婃瑙﹀彂涓嶄細鎵ц銆傛墍浠ラ渶瑕佸湪鑺傛祦涓祵鍏ラ槻鎶栨€濇兂锛屼繚璇佹渶鍚庝竴娆¤Е鍙戙€俧unctionthrottle(func,wait){//璁板綍func鐨勬渶鍚庝竴娆℃墽琛屾椂闂磍etprev=0lettimerIdreturnfunction(...args){//褰撳墠瑙﹀彂鏃堕棿锛堟椂闂存埑锛塩onstnow=Number(newDate())//+newDate()//淇濊瘉鏈€鍚庝竴娆¤Е鍙?/鐪嬩簡寰堝鏂囩珷锛屾妸娓呭畾鏃跺櫒杩欎釜姝ラ鏀惧埌2锔忊儯閲?/鎴戣寰楀簲璇ユ斁杩欓噷锛屽師鍥犲涓嬩緥瀛愯鎯炽€俰f(timerId)clearTimeout(timerId)if(now>=prev+wait){//1锔忊儯//func鏍规嵁鏉′欢鎵ц鏃讹紝闇€瑕佹洿鏂皃rev鏃堕棿prev=nowfunc.apply(this,args)}else{//2锔忊儯//姣忓崟浣嶆椂闂村彧浼氭墽琛屼竴娆?/if(timerId)clearTimeout(timerId)//涓嶅簲璇ユ斁鍦ㄨ繖閲宼imerId=setTimeout(()=>{prev=nowfunc.apply(this,args)},wait)}}}鍋囪鎴戞妸clearTimeout()鏀惧湪2锔忊儯閲岄潰鑰屼笉鏄闈€傝€冭檻涓嬮潰鍩轰簬throttle(func,1000)鐨勫満鏅細鎴?s瑙﹀彂涓€娆★紝搴旇閬靛惊1锔忊儯鐨勯€昏緫銆傜劧鍚庡湪4.9s鍐嶆瑙﹀彂锛屼細鎸夌収2锔忊儯鐨勯€昏緫锛岃褰曚竴涓畾鏃朵换鍔°€傜劧鍚庢椂闂村埌5s鐨勬椂鍊欙紝鎴戝啀瑙﹀彂涓€娆★紙鍚庨潰浼氬仠姝㈣繍琛岋級锛屽畠浼氳蛋涓€閬?锔忊儯閫昏緫锛岀劧鍚庡湪5.9s鐨勬椂鍊欙紝鍙堜細鎵цfn.apply(this,args)锛屽洜涓哄畠鏄湪5s瑙﹀彂锛屾病鏈塩learTimeout()銆傚洜姝わ紝娓呴櫎瀹氭椂鍣ㄧ殑姝ラ搴旇鏀惧湪澶栧眰锛屼繚璇佹瘡娆¤Е鍙戦兘娓呴櫎鏈€鍚庝竴涓畾鏃跺櫒锛岄伩鍏嶅湪鏌愪簺杈圭晫鎯呭喌涓嬭Е鍙戜袱娆°€傚綋鐒讹紝涓婅堪鍦烘櫙鏄悊鎯崇姸鎬侊紝瀹為檯鍦烘櫙鍙兘寰堥毦瑙﹀強杩欎簺杈圭晫銆備絾鏄粠涓ヨ皑鐨勮搴︽潵鐪嬮棶棰橈紝涔熸槸搴旇鑰冭檻鐨勩€傚啓鍒拌繖閲岋紝鎴戝湪鎯冲垰鎵嶇殑鈥滅珛鍗虫墽琛屽姛鑳介槻鎶栤€濄€傛槸涓嶆槸鏈夌偣鍍忚繖涓紭鍖栫増鐨勮妭娴侊紵鍥炶皟鍑芥暟灏嗗湪绗竴娆¤Е鍙戞椂鎵ц銆備絾涓嶅悓鐨勬槸锛岄槻鎶栦細閲嶆柊璁℃椂锛屽湪绗竴娆¤Е鍙戝悗姣忛棿闅斾竴娆¢兘浼氳Е鍙戣妭娴侊紝闈為棿闅旂偣鐨勬渶鍚庝竴娆¤Е鍙戜篃浼氭墽琛屻€傛垜鍦ㄦ补闂ㄨ緭鍏ユ涓緷娆¤緭鍏?234567890锛屽彲浠ョ湅鍒拌緭鍏ュ瓧绗?鏃舵墽琛屼簡鍥炶皟锛涗笅涓€涓緭鍏ョ殑瀛楃234鍜?7灞炰簬涓婁竴涓椂闂撮棿闅旓紝鎵€浠ュ洖璋冩棤娉曟墽琛屻€傛暡鍏ョ殑90涓瓧绗﹀簲璇ュ睘浜?涔嬪悗鐨?s寰幆锛屽洜涓烘暡鍏?涓瓧绗﹀睘浜庢渶鍚庝竴涓Е鍙戝姩浣滐紝涓嶅湪鏃堕棿鍖洪棿鍐咃紝鎵€浠ュ洖璋冧細鍦ㄦ暡鍏?鍚?s鎵ц銆傦紙鍙墦鍗版椂闂存埑鐨勫舰寮忓彲浠ョ被姣旀洿鍑嗙‘鍦拌锛塱nputElem3.current.addEventListener('keyup',throttle(request,1000))鍥涖€侀槻鎶栧拰鑺傛祦鍏跺疄鍔熻兘闃叉姈鍜屽姛鑳借妭娴侀兘鏄负浜嗛槻姝㈡煇涓簨浠跺湪鏌愭鏃堕棿琚绻佽Е鍙戞椂闂淬€備袱鑰呴兘鏄湪涓€瀹氭椂闂撮棿闅斿唴閲嶅瑙﹀彂锛屽洖璋冨嚱鏁板彧浼氭墽琛屼竴娆°€備笉鍚岀殑鏄紝闃叉姈鍔熻兘瀵规渶鍚庝竴娆¤Е鍙戞湁鏁堬紝鑰岃妭娴佸姛鑳藉绗竴娆¤Е鍙戞湁鏁堛€備笂闈㈠鍔熻兘闃叉姈鍜屽姛鑳借妭娴佽繘琛屼簡鈥滄墿灞曗€濄€傛瘮濡傚湪鍑芥暟闃叉姈涓紝澧炲姞immediate鍙傛暟锛屾帶鍒舵槸鍚︾涓€娆℃墽琛屽洖璋冦€傚湪鍑芥暟鑺傛祦涓紝鍏佽闈炴椂闂撮棿闅斿唴鐨勬渶鍚庝竴涓Е鍙戝姩浣滄湁鏁堛€傚簲鐢ㄥ満鏅細鍔熻兘闃叉姈锛坉ebounce锛夋悳绱㈠満鏅細闃叉鐢ㄦ埛杩炵画杈撳叆鑺傜渷璇锋眰璧勬簮銆倃indowresize锛氳皟鏁存祻瑙堝櫒绐楀彛澶у皬鏃讹紝浣跨敤闃叉姈鍙Е鍙戜竴娆°€傚嚱鏁皌hrottle榧犳爣浜嬩欢锛宮ousemove鎷栨斁鐩戝惉scroll浜嬩欢濡傛灉浣犺繕涓嶆槑鐧絛ebounce鍜宼hrottle鐨勫尯鍒紝鍙互鍦ㄤ笅涓€椤佃繘琛屽彲瑙嗗寲浣撻獙銆備簲銆佹墿灞曡繕鏄偅鍙ヨ瘽锛氱敓浜х幆澧冭浣跨敤Lodash搴擄紝瀵瑰簲鐨勬柟娉曟槸_.debounce()鍜宊.throttle()銆傛瘯绔燂紝Lodash缁忚繃浜嗙ぞ鍖虹殑鑰冮獙锛岃偗瀹氫細鏈夊緢澶х殑鎻愬崌銆傝€屾垜鐨勬枃绔犲彲鑳芥湁涓€浜涙垜娌℃湁鎯冲埌鐨勫満鏅垜娌℃湁澶勭悊杩囷紝鏄潰鍚戝涔犲拰闈㈣瘯鐨勶紙鎵嬪姩鐙楀ご锛夈€傚鏈変笉瓒宠鎸囧嚭馃憢~TODOList锛氳缁嗛槄璇籐odash鐨勯槻鎶栧拰鑺傛祦婧愮爜銆倃indow.requestAnimationFrame6.鍙傝€僉odashdebounce鍑芥暟闃叉姈鍜屽嚱鏁拌妭娴侊紙鍙稿緬姝e锛?/p>