비동기 처리
비동기 처리의 첫번째 사례
function getData() {
var tableData;
$.get('https://domain.com/products/1', function (response) {
tableData = response;
});
return tableData;
}
console.log(getData()); // undefined
여기서 $.get()이 ajax 통신을 하는 부분이다. https://domain.com에다가 HTTP GET 요청을 날려 1번 상품(product) 정보를 요청하는 코드이다. 좀 더 쉽게 말하면 지정된 URL에 '데이터를 하나 보내주세요'라는 요청을 날리는 것과 같다.
그렇게 서버에서 받아온 데이터는 response 인자에 담긴다. 그리고 tableData = response; 코드로 받아온 데이터를 tableData라는 변수에 저장한다. 그럼 이제 이 getData()를 호출하려면 어떻게 될까? 결과는 맨 아래 보이는 것처럼 undefined이다.
그 이유는 $.get()로 데이터를 요청하고 받아올 때까지 기다려주지 않고 다음 코드인 return tableData;를 실행했기 때문이다. 따라서, getData()의 결과 값은 초기 값을 설정하지 않은 tableData의 값 undefined를 출력한다.
이렇게 특정 로직의 실행이 끝날 때까지 기다려주지 않고 나머지 코드를 먼저 실행하는 것이 비동기 처리이다.
자바스크립트에서 비동기 처리가 필요한 이유를 생각해보면, 화면에서 서버로 데이터를 요청했을 때 서버가 언제 그 요청에 대한 응답을 줄지도 모르는데 마냥 다른 코드를 실행 안하고 기다릴 순 없기 때문이다. 위에선 간단한 요청 1개만 보냈는데 만약 100개 보낸다고 생각해보자. 비동기 처리가 아니고 동기 처리라면 코드 실행하고 기다리고, 실행하고 기다리고... 아마 웹 애플리케이션을 실행하는데 수십 분은 걸릴 것이다.
비동기 처리의 두 번째 사례
// #1
console.log('Hello');
// #2
setTimeout(function () {
console.log('Bye');
}, 3000);
// #3
console.log('Hello Again');
비동기 처리에 대한 이해가 없는 상태에서 위 코드를 보면 아마 다음과 같은 결과값이 나올 거라고 생각할 것이다.
- 'Hello' 출력
- 3초 있다가 'Bye' 출력
- 'Hello Again' 출력
- 'Hello' 출력
- 'Hello Again' 출력
- 3초 있다가 'Bye' 출력
콜백 함수로 비동기 처리 방식의 문제점 해결하기
function getData(callbackFunc) {
$.get('https://domain.com/products/1', function (response) {
callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
});
}
getData(function (tableData) {
console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
function getData(callbackFunc) {
setTimeout(function () {
callbackFunc('Bye')
}, 3000)
}
getData(function (data) {
console.log('Hello');
console.log(data);
console.log('Hello Again');
})
비유로 이해하는 콜백 함수 동작 방식
콜백 지옥
$.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);
});
위 코드는 앞의 콜백 지옥 예시를 개선한 코드입니다. 중첩해서 선언했던 콜백 익명 함수를 각각의 함수로 구분하여 정리하였다. 정리된 코드를 간단하게 살펴보자. 먼저 ajax 통신으로 받은 데이터를 parseValue() 메서드로 파싱한다. parseValueDone()에 파싱한 결과값인 id가 전달되고 auth() 메서드가 실행된다. auth() 메서드로 인증을 거치고 나면 콜백 함수 authDone()이 실행된다. 인증 결과 값인 result로 display()를 호출하면 마지막으로 displayDone() 메서드가 수행되면서 text가 콘솔에 출력된다.
마무리
출처 : https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/#%EC%BD%9C%EB%B0%B1-%EC%A7%80%EC%98%A5-callback-hell
'JavaScript > ETC' 카테고리의 다른 글
불변성 (0) | 2019.04.03 |
---|---|
Object.entries() (0) | 2019.03.29 |
async.js (0) | 2019.03.06 |
this (0) | 2019.03.05 |
렉시컬 스코핑 (0) | 2019.03.05 |