본문 바로가기
JavaScript

callback 함수에 대해

by Dodledd 2024. 4. 28.

자바 스크립트에서의 함수는 자바에서의 함수(메소드)와 다르게 객체로써 동작합니다.

 

그럼 우리는 자바에서 메소드->인자, 매개변수로 값을 전달할 수 있지만 자바스크립트는 객체인데 어떻게 전달할까요?

 

바로 callback 함수입니다. (다른말로 고차함수)

함수를 등록하기만 하고 어떤 이벤트가 발생했거나 특정 시점에 도달했을 때 시스템에서 호출하는 함수!

function print(callback) {
    callback();
}

 

콜백함수가 필요한 이유는?

 

  • 가독성이나 코드의 재사용면에서 편리하다. (잘 사용했을 시)
  • 비동기 방식으로 작성된 함수를 동기 처리하기 위해 필요하다.

여기서 잊고있었던 비동기와 동기의 차이를 짚어보면

  • 동기 : 하나의 요청이 오면 완료된 후 당므 요청을 실행하는 방식, 코드가 순차적으로 흐르게된다.
  • 비공기 : 어떤 요청이 오면 완료되기전에 다음 요청을 같이 실행, 동시에 처리해서 효율이 올라가지만
    즉시 응답하는 것이 아니기 때문에 흐름을 예측하기 힘들 수 있다.

마지막으로 제가 세미에서 구현했던 ajax + callback 함수를 설명해보겠습니다

 

먼저 어떤 함수가 실행될지 갈리는 조건함수입니다.

//우리의 메인 함수. currentPage 가져와서 검색창을 기준으로 갈라준다.
function contentsFunction(cpage, cate){
			//검색창 가져와서 값가져오기
			//셀렉트박스가져와서 값가져오기

		const searchValue = document.getElementById("searchKeyword").value;
		
		if(searchValue == "" && cate==null){
			getList({cpage: cpage}, function(data){
				drawList(data)
			})
		} else if(cate!=null  && searchValue == "") {
			console.log("cate 실행됨",cate);
			categorySearch({cpage : cpage, cate : cate}, function(data){
				drawList(data)
			})
		}else if(searchValue != "" && cate== null){
			getSearchList({cpage : cpage, searchValue : searchValue}, function(data){
				drawList(data)
			})
		}

}

 

 

 

갈리는 조건은 검색창의 값이 있거나, 카테고리가 선택됐거나, 아무것도 선택되지 않았거나 입니다.

아무것도 선택되지않으면 DB에서 모든 List를 불러오는 함수 getList를 불러옵니다.

//List = 즉 DB에서 ProductList를 가져오는 함수
function getList(data, callback){
	console.log("ajax 실행됨")
        $.ajax({
            url: "list.pr",
            dataType:"json",
            data: data,
            success: function(data){
                callback(data)
               
            },
            error: function(){
                console.log("ajax요청실패")
            }
    })
}

 

여기서 콜백이 사용되게 되는데 data는 페이징 처리를 위한 currnetPage 즉 cpage를 json형식으로 전달하여 controller->service-> Dao -> DB와 통신하여 값을 가져옵니다.

성공하면 data를 들고 callback 방금 나를 부른 함수로 돌아갑니다.

그럼 우리는 getList에서 인자로 cpage와 callback이 담겨있는 함수를 실행하여 얻은 data를 토대로 페이지를 그려주게 됩니다.

 

 

 

그려주는 함수

//index에 productList를 그려주는함수
function drawList(data){
	console.log(data)
                    let str = "";
                    let Section = document.getElementById("contents");

                    
                    for(const p of data.list){
						let day = dataFormat(p.enrollDate)
                        str += `   <a href="javascript:void(0);" onclick="toDetail(${p.goodsId}); return false;">
                        				<div class="contents-preview">
                                        <div class="thumnail">
                                           <img src="/usedArticleTrade/${p.filePath}/${p.changeName}" alt="샘플이미지">
                                        </div>
                                        <div class="thumnail-info">
                                            <div class="name-heart">
                                                <div class="name">
                                                    <p>`+p.title+`</p>
                                                </div>
                                                <div class="heart">
                                                    <img src="\img/heart.png" alt="">
                                                    <p>`+p.loveIt+`</p>
                                                </div>
                                            </div>
                                            <div class="price-beforeDay">
                                                <div class="price">
                                                    <p>`+p.sellPrice+`</p>
                                                </div>
                                                <div class="beforeDay">
                                                    <p id="eDate">`+day.getFullYear()+-+(day.getMonth()+1)+-+day.getDate()+`</p>
                                                </div>
                                            </div>
                                        </div>
                                    </div></a>`
                                    
                    }
                    Section.innerHTML = str;
                    
                    let pagi = document.getElementById("pagination");
                    
                    let pagingStr = "";

                    if (data.pi.currentPage != 1) {
                        pagingStr += `<button onclick="contentsFunction(${data.pi.currentPage - 1 });">&lt;</button>`;
                    }
                    for (let p = data.pi.startPage; p <= data.pi.endPage; p++) {
                        if (p == data.pi.currentPage) {
                            pagingStr += `<button disabled>`+p+`</button>`;
                        } else {
                            pagingStr += `<button onclick="contentsFunction(${p});">`+p+`</button>`;
                        }
                    }
                    if (data.pi.currentPage != data.pi.maxPage) {
                        pagingStr += `<button onclick="contentsFunction(${data.pi.currentPage + 1 });">&gt;</button>`;
                    }

                    pagi.innerHTML = pagingStr;
}

 

위 함수는 페이징처리하는 페이징 바까지 ajax 통신하여 다시 그려주는 방식으로 선택했습니다.

 

만약 search 값이 있을 때를 보면

//search하는 함수
function getSearchList(data, callback){
		$.ajax({
	            url: "search.pr",
	            dataType:"json",
	            data: data,
	            success: function(data){
	                callback(data)
	               
	            },
	            error: function(){
	                console.log("ajax요청실패")
	            }
	    })
}

위에서 ajax로 보내주는 데이터는 searchBar에 입력한 keyword와 페이징 처리를 위한 cpage를 json형식으로 보냈고 마찬가지로 controller->service-> Dao -> DB와 통신하여 값을 가져옵니다. 그러면 다시 drawList함수를 불러서 페이지를 그려주게 됩니다.

 

 

처음에는 이렇게 구성하지 않고 하나의 함수안에 여러가지 기능을 넣어 만들었었는데 완성하고 보니 너무 읽기 힘들어서

한 번 갈아엎는 리팩토링을 진행해본 결과 하나의 함수에는 한개의 기능만 넣어 코드의 재사용성과 callback함수를 이용하여 가독성을 높이는 결과를 얻었습니다.

 

뭐랄까 활용성이 아주 큰 지식을 하나 얻은 기분이였습니다.

'JavaScript' 카테고리의 다른 글

Ajax에 대하여  (0) 2024.04.05
정규식 표현  (0) 2024.03.24
부트스트랩 사용법  (2) 2024.03.24
jQuery에 대하여  (0) 2024.03.21
[4일차] window용 객체, 이벤트  (0) 2024.03.20