JavaScirpt #콜백함수 (Callback Function)

JohnKim·2021년 8월 13일
0

javascript

목록 보기
20/26

콜백함수? 📞 🔙 🗂

정의

함수의 매개변수가 함수일 때, 매개변수로 받은 함수를 콜백함수라 부른다.

일반적으로 비동기를 처리하기 위해 콜백패턴을 사용한다.

어떤 이벤트가 발생했거나 특정 시점에 도달 했을 때 시스템에서 호출하는 함수이기도 하다.

Callback함수를 사용하는 경우 ⁉️

1. 사용자 이벤트처리

window.addEventListener('keydown', e => {
	// 로직
});

브라우저 화면에서 발생하는 사용자의 이벤트는 예측이 불가능하다.
따라서 이런 화면이벤트를 관리담당하는 녀석에게 우리는 특정이벤트가 발생할 때 호출을 원하는 내용을 callback 함수에 전달하게 된다.

2.네트워크 응답 처리

화면단에서 서버에게 요청을 보냈을 때, 그 응답이 언제 올지 알 수 없다.
따라서 이런 서버에 대한 응답처리 등도 비동기적으로 처리해야 한다.

3. 일반함수에서의 호출(sync callback)

///1
function showMessage(msg, closeFn) {
	// 로직
	
	closeFn(true);
}

///2
[1,2,3].map(el => el*2);

4.의도적으로 시간 지연을 사용하는 기능

setTimeout은 콜백함수의 실행을 지정된 밀리초만큼 지연하는 내장함수이다.

setTimeout(function(){ 
	alert("Hello"); 
}, 3000);

콜백지옥 💢💢💢💢💢

콜백 지옥(callback hell)은 콜백 함수를 익명 함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 감당하기 힘들정도로 깊어지는 현상을 말한다. 주로 이벤트 처리나 서버 통신과 같은 비동기적인 작업을 수행하기 위해 이런 형태가 자주 등장하는데, 가독성이 떨어지면서 코드를 수정하기 어렵다.

예리님의 강의를 듣던 도중 엣날 옛적 jQuery 를 통해 콜백지옥이 된 로직을 예제로 볼 수 있었다.

(async/await가 없던 시절.. promise도 없던 시절은 XMLHttpRequest 라는 내장 객체를 이용해서 api를 호출했었다고 한다.....)

으 ,,,, 이게 무슨코드여,,,😭

상품 목록 페이지인데, 목록정보에 후기 정보도 같이 보이는 로직을 구현중이다.

백엔드에서 하나에 API에 담아 주는것이라니라 상품목록 따로, 후기 따로 api가 나누어져 있었다.

  1. 상품 목록을 가져온다.
  2. 가져온 상품 목록 중에서 첫 상품의 id로 해당 상품의 후기 api를 호출한다.
  3. 가져온 후기 중에서 첫 후기의 id로 좋아요 수를 가져오는 api를 호출한다.
$.get('https://api.test.com/proudcts', function(response) {
	var firstProductId = response.products[0].id;

	$.get('https://api.test.com/proudct/comments?id='+firstProductId, function(response) {
		var firstCommentId = response.comments[0].id;
	
		$.get('https://api.test.com/proudct/comment/likes?id='+firstCommentId, function(response) {
			var likes = response.likes;
			var likesCount = likes.length;

			// 첫번째 상품의 -> 첫번째 후기의 좋아요 수 화면에 적용!
		});
	});
});

이전에는 정말 흔했던 코드라고한다...

위와 같이 코드를 작성하게 되면 가독성이 매우떨어져 유지 보수 하기도 힘든 코드가 된다.

콜백지옥 탈출 방법!! 🧐

비동기적인 작업을 수행하기 위해 콜백함수를 익명함수로 전달하는 과정에서 생기는 콜백 지옥을 Promise, Generator, async/await등을 사용해서 방지할 수 있다.

👇async/await을 사용하고 익명함수들을 기명함수로 바꿔주었다.

(async () => {
	try {
	  let productResponse = await fetch('https://api.test.com/proudcts');
	  let firstProductId = productResponse.products[0].id;

	  let commentResponse = await fetch('https://api.test.com/proudct/comments?id='+firstProductId);
		let firstCommentId = commentResponse.comments[0].id;

	  let likeResponse = await fetch('https://api.test.com/proudct/comment/likes?id='+firstCommentId);
		let likesCount = likeResponse.likes.length;
	} catch(error) {
		console.log(error);
	}
})();

0개의 댓글