이전 포스팅에서 알아본 비동기 처리를 사례를 통해서 알아보자.
function getData() {
var tableData;
$.get('https://domain.com/products/1', function(response) {
tableData = response;
});
return tableData;
}
console.log(getData()); // undefined
해당 코드는 ajax 통신으로 HTTP GET 요청을 날려 데이터를 받아오는 비동기 처리 코드이다.
해당 코드가 통신을 잘 주고받았는지 결과값을 한번 봐보자 console.log(getData()); // undefined 결과 값으로 undefined가 출력된다. 요청 코드가 잘못된거라고 생각할 수 있겠지만 undefined가 출력된 이유는 response인자에 요청한 데이터가 담기기도전에 다음코드인 return tableData; 코드를 실행해버렸기 때문이다.
// #1
console.log('Hello');
// #2
setTimeout(function() {
console.log('Bye');
}, 3000);
// #3
console.log('Hello Again');
두번째 사례는 Web API의 한 종류인 setTimeout이다.
setTimeout은 간단하게 셋팅한 시간만큼 기다렸다가 함수 내부의 로직을 실행하는 코드이다.
비동기 처리를 정확하게 이해하지 못했다면 위의 코드 결과값은 아래처럼 나온다 생각할 것이다.
'Hello'
3초 대기 후 'Bye'
'Hello Again'
하지만 실제 출력되는 결과 값은 아래와 같이 출력된다.
'Hello'
'Hello Again'
3초 대기 후 'Bye'
setTimeout도 비동기 방식으로 실행되기 때문에 setTimeout이 실행되면 Web API로 이동된 후
다음 코드들을 처리한 후 다시 CALL STACK으로 올라와 실행이 된다.
ajax와 setTimeout을 활용하여 작성된 코드들로 비동기 처리 방식의 사례를 알아보았으니
콜백 함수를 활용하여 본격적인 비동기 처리 코드를 작성해보도록 하자.
function getData(callbackFunc) {
$.get('https://domain.com/products/1', function(response) {
callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
});
}
getData(function(tableData) {
console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
해당 코드는 위에서 ajax로 작성했던 사례 코드의 undefined가 출력되는 문제를 콜백 함수를 통해 개선한 코드이다. 콜백 함수 동작 방식에 대해 완벽하게 이해할 수 있도록 작성된 너무 좋은 예시를 인용하였다.
비유로 이해하는 콜백 함수 동작 방식
콜백 함수의 동작 방식은 일종의 식당 자리 예약과 같습니다.
일반적으로 맛집을 가면 사람이 많아 자리가 없습니다. 그래서 대기자 명단에 이름을 쓴 다음에 자리가 날 때까지 주변 식당을 돌아다니죠.
만약 식당에서 자리가 생기면 전화로 자리가 났다고 연락이 옵니다.
그 전화를 받는 시점이 여기서의 콜백 함수가 호출되는 시점과 같습니다. 손님 입장에서는 자리가 날 때까지 식당에서 기다리지 않고 근처 가게에서 잠깐 쇼핑을 할 수도 있고 아니면 다른 식당 자리를 알아볼 수도 있습니다.자리가 났을 때만 연락이 오기 때문에 미리 가서 기다릴 필요도 없고, 직접 식당 안에 들어가서 자리가 비어 있는지 확인할 필요도 없습니다. 자리가 준비된 시점, 즉 데이터가 준비된 시점에서만 저희가 원하는 동작(자리에 앉는다, 특정 값을 출력한다 등)을 수행할 수 있습니다.
$.get('url', function(response) {
parseValue(response, function(id) {
auth(id, function(result) {
display(result, function(text) {
console.log(text);
});
});
});
});
위와 같은 코드 구조를 콜백 지옥이라고 하는데, 쉽게 정리하면 콜백 함수 내부에 콜백을 계속 무는 형식을 말한다. 이는 코드의 가독성을 떨어뜨리고 유지보수 측면이나 에러 발생 시 디버깅 작업을 생각하면 어질어질한게 문제점이다.
콜백 지옥을 코딩 패턴으로 해결한다면 아래와 같이 콜백 함수를 분리하여 가독성을 챙길 수 있다..
function parseValueDone(id) {
auth(id, authDone);
}
function authDone(result) {
display(result, displayDone);
}
function displayDone(text) {
console.log(text);
}
$.get('url', function(response) {
parseValue(response, parseValueDone);
});
다음 포스팅은 더욱 효율적으로 비동기 처리 코드를 작성 할 수 있는 Promise에 대해 알아보자.
References