Javascript: 콜백 함수와 콜백 지옥

yellowbutter·2023년 3월 19일
0

javascript

목록 보기
6/6
post-thumbnail

콜백 함수란?

콜백 함수는 함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수를 말한다. 고차 함수에 의해 호출되며, 필요에 따라 인수를 전달받을 수 있다.

콜백 함수가 필요한 이유

자바스크립트는 비동기 프로그래밍을 위해 설계된 언어로, 이벤트 처리와 같은 작업에 유용하다. 비동기 프로그래밍은 한 명령의 응답을 기다리는 동안 다음 명령을 수행하여 속도를 향상시킬 수 있다.

자바스크립트 엔진은 싱글 스레드로 동작하기 때문에 한 번에 하나의 명령만 처리할 수 있다. 따라서 한 명령의 응답이 오래 걸릴 경우 전체적인 실행 속도가 저하될 수 있다. 하지만 비동기적 프로그래밍 방식을 사용하면 자바스크립트 엔진은 브라우저나 Node.js와 같은 환경에서 제공하는 Web API에 작업을 맡기고, 다음 명령들을 수행하여 빠른 속도를 유지할 수 있다.

비동기적 프로그래밍을 사용하는 경우

  1. 사용자 이벤트 처리: 브라우저에서는 사용자가 언제 어떤 이벤트를 발생시킬지 예측할 수 없다. 따라서 원하는 이벤트가 발생했을 때 실행하고자 하는 함수를 콜백 함수로 전달할 수 있다.

  2. 네트워크 응답 처리: 서버로부터 데이터를 요청하면 응답이 언제 도착할지 알 수 없습니다. 비동기적으로 응답을 처리하는 것이 유용하다.

  3. 의도적인 시간 지연: 일정 시간이 지난 후에 작업을 수행하고자 할 때는 setTimeout과 같은 함수를 사용하여 비동기적으로 처리할 수 있다.

동기 함수와 비동기 함수 예시

동기 함수:

// 동기 함수
console.log('1');
console.log('2');
console.log('3');
// 출력 결과: 1 2 3

동기 함수는 순서대로 실행되기 때문에 예상한 대로 출력된다.

비동기 함수:

// 비동기 함수
console.log('1');
setTimeout(() => {
  console.log('2');
}, 1000);
console.log('3');
// 출력 결과: 1, 3, 2

비동기 함수는 실행 순서가 순서대로 일어나지 않는다.
중간에 명령문이 처리되는 동안 다음 명령문은 기다리지 않고 실행되기 때문에 예측하기 어렵고, 결과는 1, 3, 2와 같이 나타난다.

콜백 지옥

콜백 지옥(callback hell)은 비동기 프로그래밍에서 발생하는 문제로, 콜백 함수가 반복되어 코드의 들여쓰기 수준이 매우 깊어지는 현상을 말한다.

step1(function(value1) {
    step2(function(value2) {
        step3(function(value3) {
            step4(function(value4) {
                step5(function(value5) {
                    step6(function(value6) {
                        // value6을 처리하는 코드
                    });
                });
            });
        });
    });
});

위 코드는 step1부터 step6까지의 함수가 순차적으로 실행되는 상황을 나타낸다.
각 함수는 처리가 완료되면 결과 값을 전달받아 다음 단계의 함수를 호출하는 방식이. 하지만 이런 구조는 코드의 가독성을 해치며 유지보수가 어렵고 실수하기 쉽다.

에러 처리까지 고려한 콜백 지옥의 예시 코드는 다음과 같다.

step1(function(err, value1) {
    if (err) {
        console.log(err);
        return;
    }
    step2(function(err, value2) {
        if (err) {
            console.log(err);
            return;
        }
        step3(function(err, value3) {
            if (err) {
                console.log(err);
                return;
            }
            step4(function(err, value4) {
                // ...
            });
        });
    });
});

에러 처리를 포함한 콜백 지옥은 코드의 가독성을 더욱 저하시키고, 실수가 발생할 가능성을 높인다.

따라서 이러한 콜백 지옥에 빠지지 않도록 코드를 개선해야 한다.

Promise 객체를 사용하여 콜백 지옥 해결하기

콜백 지옥을 해결하기 위해 Promise 객체를 사용할 수 있다.
Promise는 비동기 작업의 완료 또는 실패를 나타내는 객체로, 콜백 함수 대신 체이닝을 통해 비동기 작업을 처리할 수 있다.

Promise를 사용한 예시 코드는 다음과 같다:

step1()
    .then(function(value1) {
        return step2();
    })
    .then(function(value2) {
        return step3();
    })
    .then(function(value3) {
        return step4();
    })
    .then(function(value4) {
        // ...
    })
    .catch(function(error) {
        console.log(error);
    });

위 코드에서 각 단계의 함수(step1, step2 등)는 Promise를 반환하도록 구현되어야 한다.
리턴된 Promise는 .then() 메서드를 이용하여 다음 단계의 함수를 연결한. 이를 통해 콜백 지옥을 피할 수 있다. 각 단계의 함수에서는 비동기 작업이 완료되면 resolve()를 호출하여 성공 결과를 전달하고, 오류가 발생하면 reject()를 호출하여 실패를 전달한다.

.catch()는 앞선 .then() 체인에서 발생한 오류를 처리하기 위해 사용된다.

더욱 직관적인 코드를 작성하기 위해 ES6에서는 async/await 구문을 사용할 수 있다. async/await를 사용하면 Promise를 보다 간결하고 동기적인 코드와 유사하게 작성할 수 있다.

async function process() {
    try {
        const value1 = await step1();
        const value2 = await step2();
        const value3 = await step3();
        const value4 = await step4();
        // ...
    } catch (error) {
        console.log(error);
    }
}

process();

process() 함수 내부에서 await 키워드를 사용하여 비동기 작업이 완료될 때까지 기다린다. 이를 통해 코드가 동기적으로 실행되는 것처럼 보이게 된다. 오류 처리는 try/catch 블록을 이용하여 수행된다.

위와 같이 async/await를 사용하면 비동기 코드를 보다 직관적이고 가독성 좋게 작성할 수 있으며, 콜백 지옥을 피할 수 있다.

요약하자면, 콜백 함수는 함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수이며, 비동기 프로그래밍에서 콜백 지옥이 발생할 수 있다. 이를 해결하기 위해 Promise 객체나 async/await를 사용하여 보다 간결하고 가독성 좋은 비동기 코드를 작성할 수 있다.

참고 자료
콜백 지옥 탈출하기! 비동기 처리 방법
ㅓavaScript | 콜백 함수와 콜백 지옥

profile
기록은 희미해지지 않는다 🐾🧑‍💻

0개의 댓글