자바스크립트

 

쓰로틀 (Throttle)

먼저, 쓰로틀은 이벤트를 일정 주기로 발생시키는것을 목적으로 합니다.
대표적으로 사용되는 예는 포털이나 쇼핑몰과 같이 검색이 필요한 사이트에서 유저가 검색을 위해 키보드 이벤트가 발생했을 때 추천검색어를 보여주는 경우입니다.

키보드 이벤트의 경우 짧은 시간에 많이 발생하는 이벤트입니다.
특히, 한글의 경우 자음과 모음을 조합하는 형태로 사용하기 때문에 예를 들어 "언제"라는 단어를 검색한다고 한다면 ㅇ, 어, 언, 얹, 언제에서 모든 키 입력이 발생하고 ㅇ, 어, 얹 과 같은 단어는 굳이 호출할 필요가 없는 단어입니다.

 

<script>
const inputBox = document.querySelector("#updateMonthlyBranchTxt");

//Throttle
let timer;
function throttle(callbackFn, timeout) {
 if(!timer) {
     timer = setTimeout(() => {
         timer = null;
         callbackFn();
     }, timeout);
 }
}

inputBox.addEventListener("keyup", (e) => {	 
	 const content=e.target.value;	 
	 throttle(() =>{
		 $.ajax({
			  url: "sub_017_ok.php",
			  type:"post",
			  data: {
				  content		
			  },	      	     
		      success:function(data){
		        console.log("data : ",data);
		        data = JSON.parse(data);
		        console.log("data : ",data);	     
		      },
		      error:function(error){
		        console.log("error : ",error);
		      }
		 });	
	 
	 },500);
	 
});
</script>

 

 

 

 

 

디바운스 (Debounce)

디바운스는 일정시간 내에 반복적으로 이벤트가 발생했을 때 이벤트 횟수와 관계없이 마지막 이벤트가 발생한 후 일정시간 뒤에 콜백함수를 한번만 호출하는 기법입니다.

대표적으로 resize 이벤트의 경우 조금만 사이즈를 변경해도 이벤트가 어마어마하게 발생합니다.
만약, 이 이벤트가 발생했을 때마다 무거운 연산이 필요한 로직이 콜백함수에 포함되어 있다면 이는 성능에 무리를 줄 수 있습니다.

 

et timer;
function debounce(callbackFn, timeout) {
    if(timer) {
        clearTimeout(timer);
    }

    timer = setTimeout(() => {
        callbackFn();
    }, timeout);
}

window.addEventListener("resize", () => {
    console.log("event");
    debounce(() => console.log("debounce!"), 200);
});

 

 

 

출처:

https://velog.io/@sisofiy626/JavaScript-%EC%93%B0%EB%A1%9C%ED%8B%80throttle%EA%B3%BC-%EB%94%94%EB%B0%94%EC%9A%B4%EC%8A%A4debounce

 

 

 

리액트에서   useDebounce Cusotm Hooks 만들기

 

 

src/hooks/useDebounce.js

import { useEffect, useState } from 'react'



export const useDebounce=(value, delay) => {
    const [debounceValue, setDebounceValue] = useState(value);

    useEffect(() => {
     
        const handler = setTimeout(() => {
            setDebounceValue(value);
        }, delay);


        return()=>{
            clearTimeout(handler);
        }

    },[value, delay]);

    return debounceValue;
}

 

 

 

 

import _ from 'lodash';
import React, { useEffect, useState } from 'react'
import { useLocation, useNavigate } from 'react-router-dom';
import { axiosInnstance } from '../../api/axios';
import './SearchPage.css';
import { useDebounce } from '../../hooks/useDebounce';

//Throttle
// let timer;
// function debounce(callbackFn, timeout) {
//   if(timer) {
//       clearTimeout(timer);
//   }

//   timer = setTimeout(() => {
//       callbackFn();
//   }, timeout);
// }



const SearchPage = () => {
  const [searchResults, setSearchResults] = useState([]);
  const navigate=useNavigate();


  const useQuery = () => {
    return new URLSearchParams(useLocation().search);
  };

  let query=useQuery();
  //const searchTerm=query.get('q');
  const debounceSearchTerm=useDebounce(query.get('q'), 500);


  useEffect(() => {
    if(debounceSearchTerm){
      fetchSearchMovie(debounceSearchTerm);   
    }
  }, [debounceSearchTerm]);




  const fetchSearchMovie = async(debounceSearchTerm) => {
      try {
        const response=await axiosInnstance.get(`/search/multi?include_adult=false&query=${debounceSearchTerm}`);
        setSearchResults(response.data.results);
            
      } catch (error) {
        console.error('error ',error);
      }
  }
  

  if(searchResults.length > 0){
    return (
      <section className='search-container'>
          {
            searchResults.map((movie) => {
             
              if(movie.backdrop_path!=null && movie.media_type!=="person"){
                  const moiveImageUrl=`https://image.tmdb.org/t/p/w500${movie.backdrop_path}`;

                    return  (
                        <div className='movie' key={movie.id}>
                          <div className='movie__column-poster' onClick={()=>navigate(`/${movie.id}`)}>
                            <img src={moiveImageUrl} alt={movie.title}  className='movie__poster'     />
                           </div>                           
                        </div>
                    );
                      
               }else{
                    return null;
               }
            
            })

            
          }
      </section>
    )

  }else{

      return (
        <section className='no-results'>
          <div className='no-results__text'>
            <p>
                찾고자하는 검색어 "{debounceSearchTerm}"  에 맞는 영화가 없습니다.
            </p>
          </div>
        </section>
      )
  }
  


}

export default SearchPage

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

인간의 정신은 육체에 큰 영향을 가지고 있다. 따라서 질병이 생기는 원인도 정신, 그 자체 속에 있다고 볼 수 있다. -모리에르

댓글 ( 4)

댓글 남기기

작성

자바스크립트 목록    more