자바 스크립트에서의 함수는 자바에서의 함수(메소드)와 다르게 객체로써 동작합니다.
그럼 우리는 자바에서 메소드->인자, 매개변수로 값을 전달할 수 있지만 자바스크립트는 객체인데 어떻게 전달할까요?
바로 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 });"><</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 });">></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 |