[JS] 비동기 프로그래밍(1) : 콜백 함수(Callback Function)

안녕하세요. 오늘은 자바스크립트 비동기 프로그래밍 함수인 콜백 함수에 대해 알아보도록 하겠습니다.

 

 

 

콜백 함수란?

  • 다른 함수에 매개변수로 전달되어 나중에 실행되는 함수
  • 즉, 특정 작업이 완료되거나 특정 이벤트가 발생했을 때 호출되는 함수를 의미함
function greeting(name) {
	console.log(`Hello, ${name}!`);
}

function userInput(callback) {
	const name = "뭉이";
    callback(name);
}

userInput(greeting); // Hello, 뭉이!

위 코드에서 'greeting' 함수는 콜백 함수로 사용되고, 'userInput' 함수는 매개변수로 콜백 함수를 받아 이를 호출하여 'greeting' 함수를 실행함

 

 

 

콜백 함수 사용 사례

1. 비동기 작업 처리

  • 자바스크립트는 단일 스레드 언어로 비동기 작업을 효과적으로 처리하기 위해 콜백 함수를 많이 이용함
  • 비동기 작업을 수행하는 함수(Ex. 타이머, 이벤트 핸들러 등)는 작업이 완료되면 콜백 함수를 호출함

예시) 'setTimeout'을 사용한 콜백 함수

아래 코드에서 'setTimeout' 함수는 2초 후 콜백 함수를 실행함. 여기서 콜백 함수는 익명 함수로 '끝'을 출력

function waitAndRun() {
    setTimeout(() => {
        console.log('끝');
    }, 2000);
}
waitAndRun(); // 2초 후 '끝' 출력

 

 

2. 이벤트 처리

  • 사용자가 버튼을 클릭하거나 입력 필드에 타이핑할 때마다 콜백 함수가 호출되어 이벤트를 처리함

예시) 이벤트 핸들로서의 콜백 함수

아래 코드에서 'addEventListener'는 'click' 이벤트가 발생했을 때 호출할 콜백 함수를 매개변수로 받음

document.getElementById('myBtn').addEventListener('click', function() {
    console.log('버튼이 클릭되었습니다.');
});

 

3. 배열 메서드

  • JS 배열 메서드 중 많은 수가 콜백 함수를 사용함
  • 예를 들면 forEach, map, filter 등의 메서드는 배열의 각 요소에 대해 콜백 함수를 실행함

예시) 배열 메서드에서의 콜백 함수

아래 코드에서 forEach 메서드는 배열의 각 요소에 대해 콜백 함수를 호출하여 두 배의 값을 출력함

const numbers = [1, 2, 3, 4, 5];

numbers.forEach(function(number) {
	console.log(number * 2);
}); // 2 4 6 8 10

 

 

 

콜백 지옥(Callback Hell)

비동기 작업이 중첩될 때 콜백 함수가 많이 사용되면 코드의 깊이가 깊어지고 가독성이 떨어지며 유지보수가 어려워지는 문제가 발생할 때 이것을 콜백 지옥이라고 함

function waitAndRun2() {
	setTimeout(() => {
		console.log('1번 콜백 끝');
	
		setTimeout(() => {
			console.log('2번 콜백 끝');

			setTimeout(() => {
				console.log('3번 콜백 끝');
			});
		}, 2000);
	}, 2000);
}
console.log(waitAndRun2()); // 2초 간격으로 '1번 콜백 끝', '2번 콜백 끝', '3번 콜백 끝' 출력
// 2초를 기다린 다음에 또 2초를 기다리고 또 2초를 기다리고..~~ 함수 실행

 

콜백 지옥 해결 방법

  • 이름 있는 함수 사용 : 콜백을 익명 함수가 아닌 이름 있는 함수로 정의하여 가독성을 높임
  • 프로미스(Promise) 사용 : 프로미스를 사용하면 콜백 지옥을 피하고 비동기 작업을 명확하게 표현할 수 있음
  • async/await 사용 : 프로미스와 함께 사용하여 비동기 코드를 동기 코드처럼 작성할 수 있음