[JS기록] 중복된 함수 하나로 합쳐버리기 (feat. callback)

개인 프로젝트 진행중 내가 짠 코드가 너무나도 마음에 들지 않아서 코드 수정을 해보았다.

(이번에도 박학하신 튜터님께 많은 도움을 받았음) 

어쨋든 이번 글은 100% 기록 목적이고 수정한 영역에 대해서 아직 완전히 이해를 한게 아니기 때문에

정리가 아주 중구난방일 것이다는 예고 (대충 정리하겠다는 소리 맞음)


기존 코드

// api 데이터 가져오는 함수 (fetchData)
async function fetchData(searchCriteria, searchKey, processData) {
	const data = await fetch(.......)	// api 데이터 받아옴
    processData(data)	// 받은 데이터를 콜백함수로 다시 전달
}

// 호출한 부분 (순서대로 인기, 장르, 개봉예정 영화 받아옴)
fetchData(topRated, "", processPopularityData);
fetchData(genres, "", processGenresData);
fetchData(upcoming, "", processUpcomingData);

// callback함수로 쓰일 재료들
const processGenresData = (data) => {
    const subContainer = createSubContainer("비슷한 장르!비슷한 장르!비슷한 장르");
    data.forEach(data => {
    	// 대충 데이터 생성하는 코드
    });
}

const processUpcomingData = (data) => {
    const subContainer = createSubContainer("커밍순!커밍순!커밍순!");
    data.forEach(data => {
    	// 대충 데이터 생성하는 코드 (위와 동일)
    });
}

 

순서 정리

  1. fetchData()에 인자로 `callback` 함수를 넣어줌
  2. 그럼 fetchData()가 데이터를 가져오는 작업을 완수하고
  3. `callback` 함수에 data를 전달함
  4. data를 전달 받은 `callback` 함수에서 데이터를 처리함

문제점

  • 비슷한 장르, 개봉예정영화, 인기영화 .... 등등등 받아오는 데이터는 달라도 코드 동작 방식은 거의 유사함
    • 데이터를 받아온다 -> 데이터를 HTML 요소를 생성하는 함수에 전달한다 (html 요소도 똑같이 생겼고, 이건 다행히 하나의 함수에서 처리함)
    • 근데 HTML 요소의 제목(?) 이라고 해야하나 딱 그 부분 텍스트 하나만 다르게 주어야함

내가 생각한 해결 방법

  • fetchData()에 인자를 하나 더 넣어주는 방법
  • (`callback`) -> (`callback`, `headerTitle`)
  • `headerTitle`을 전달 -> 전달 -> 전달 ... 해서 쓰기
  • 가장 머리 안쓰고 중복되는 함수를 줄일 수 있는 방법이었지만 에바라고 생각이 들었음 (인자 하나 추가할때마다 모든 함수에 추가해야하기 때문)

 


개선 방법

(1) 원래 인자로 넣었던 `callback` 함수를 화살표 함수로 바꾸고 그 안에 원래 `callback` 함수를 넣어줌

// 원래 호출방법
// fetchData(topRated, "", processUpcomingData);

// 개선
fetchData(topRated, "", (data) => {
    processMovieData(data, "커밍순!커밍순!...")
})
  • 기존 `callback`함수가 매개변수로 받던 `data`를 화살표 함수가 받도록 변경
  •  화살표함수안에 함수를 넣음과 동시에, `data` 와 `제목`을 같이 넣어줌 

 

(2) 그러면 기존 `callback` 함수에서 통합된 함수로 바뀌어버린 함수를 봐보자.

const processMovieData = (data, text) => {
    const subContainer = createSubContainer(text); // 하드코딩으로 넣은 제목을, text변수로 변경
    data.forEach(data => {
    	// 대충 데이터 생성하는 코드 (위와 동일)
    });
}
  • 원래는 하드코딩으로 텍스트를 적었지만, text라는 매개변수를 추가해줌으로서 전달받을 수 있게 되었다. 

동작원리

  • 화살표함수도 함수이기 때문에 `fetchData()` 는 기존과 똑같이 동작을 함 (어떠한 수정도 없음)
  • `fetchData()`에서 화살표함수(이제 얘가 callback함수)에 `data` 를 전달하면
  • 다시 `data`를 새로 통합된 함수에 전달해주고, 동시에 제목(`text`)을 같이 전달해줌
  • 그리고 기존의 하드코딩된 제목을 `text` 변수로 대체 함으로써 통합 가능

 

가장 큰 장점

  • 내가 생각했던 구질구질한 방법도 함수를 통합할 수'는' 있었다.
  • 하지만 거쳐가는 모든 함수에서 매개변수를 추가해주어야하는 문제가 있었다. (유지보수성의 문제)
  • 새로 찾아낸 방법은 `fetchData()` 부분은 일절 건드리지 않고 최상위 호출 부분만 변경해주면 나머지는 신경쓰지 않아도 됨

 

 

 

 

댓글

Designed by JB FACTORY