javascript

[Javascript] 비동기(async) 처리와 콜백(callback) 함수

sewonzzang123 2021. 12. 28.
반응형

 

비동기 처리?

자바스크립트의 비동기 처리란 특정 코드의 연산이 끝날 때 까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성을 의미합니다.

 

비동기 처리의 예시 1 - ajax

ajax는 제이쿼리의 비동기 처리입니다. 제이쿼리로 웹 서비스를 제공할 때 ajax를 빼 놓을 수 없습니다.

보통 화면에 표시할 이미지나 데이터를 서버에서 불러와 표시해야 하는데 이때 ajax통신으로 해당 데이터를 서버로부터 가져올 수 있습니다.

function getData(){
	var response = {};
    $.get('http://domain/products/1', function(response){
    		response = response;
            });
      	return response;
 }
 
 console.log(getData()); // undefined

여기서 $.get() 이 ajax 통신을 하는 부분입니다.

http://domain 에 HTTP GET 요청을 날려 1번 product를 요청하는 코드입니다.

즉, '지정된 url 에 데이터를 하나 보내주세요' 라는 요청을 보내는 것입니다.

 

그렇게 받아온 데이터는 response 인자에 담기는데, 이것을 response = response 로 받아 response라는 변수에 저장을 합니다.

이제, getData() 를 하게 된다면 어떻게 될까요?

response 가 나와야 할 것 같지만 undefined 가 나오게 됩니다.

 

왜 undefined 가 나올까요? 그것은 $.get() 로 데이터를 요청하고 받아올때까지 기다리지 않고 바로 return response를 했기 때문입니다.

따라서, getData() 의 결과 값은 초기값을 설정하지 않은 tableData의 값 undefined를 출력합니다.

 

이렇게 특정 로직의 실행이 끝날 때 까지 기다려주지 않고 나머지 코드를 먼저 실행하는 것이 비동기 처리 입니다.

왜 비동기 처리가 필요한지를 생각해보면, 화면에서 서버로 데이터를 요청했을 때 서버가 언제 그 요청에 대한 응답을 줄지도 모르는데 마냥 다른 코드를 실행 안하고 기다릴 순 없기 때문입니다, 

만약 동기처리라면 코드 실행하고, 기다리고... 웹 애플리케이션을 실행하는데 수십 분은 걸릴 것 입니다.

 

비동기 처리의 예시 2 - setTimeout()

또 다른 비동기 처리 사례는 setTimeout() 입니다. setTimeout() 은 web API 의 한 종류 입니다. 코드를 바로 실행하지 않고 지정한 시간만큼 기다렸다가 로직을 실행합니다. 아래 코드입니다.

// 1
console.log('hello');
// 2
setTimeout(()=>{
	console.log('bye');
    },3000);
// 3
console.log('world!');

- 'hello'

- 'world!'

- 3초 뒤 'bye'

 

setTimeout() 역시 비동기 방식으로 실행되기 때문에 3초를 기다렸다가 다음코드를 수행하는 것이 아니라, 

setTimeout() 을 실행하고 나서 다음 코드인 console.log('world!')로 넘어갔습니다.

 

콜백 함수로 비동기 처리 방식의 문제점 해결하기

앞에서 자바스크립트 비동기 처리 방식에 의해 야기될 수 있는 문제들을 살펴봤습니다.

이러한 문제들은 어떻게 해결할 수 있을까요? 바로 콜백(callback) 함수를 이용하는 것입니다. ajax 통신 코드를 콜백 함수로 개선해보겠습니다.

function getData(callbackFunc){
	$.get('http://domain/products/1', function(response){
    	callbackFunc(response); //서버에서 받은 response를 callbackFunc()함수에 넘겨줌.
    });
}

getData(function(response){
	console.log(response); //$.get() 의 response가 response에 전달됨.
});

이렇게 콜백 함수를 사용하면 특정 로직이 끝났을 때 원하는 동작을 실행시킬 수 있습니다.

 

콜백 지옥 (callback hell)

콜백 지옥은 비동기 처리 로직을 위해 콜백 함수를 연속해서 사용할 때 발생하는 문제입니다. 아마 다음과 같은 코드를 본 적이 있을 것입니다.

$.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){
	parseValueDone(response, parseValueDone);
}

위 코드는 앞의 콜백 지옥 예시를 개선한 코드입니다.

중첩해서 선언했던 콜백 익명 함수를 각각의 함수로 구분하였습니다.

정리된 코드를 간단하게 살펴보면, 먼저 ajax 통신으로 받은 데이터를 parseValue() 메서드로 파싱합니다.

parseValueDone() 에 파싱한 결과값인 id가 전달되고 auth() 메서드가 실행됩니다.

auth() 메서드로 인증을 거치고 나면 콜백 함수 authDone()이 실행됩니다.

인증 결과 값인 result 로 display()를 호출하면 마지막으로 displayDone() 메서드가 수행되면서 text가 콘솔에 출력됩니다.

 

위와 같은 코딩 패턴으로도 콜백 지옥을 해결할 수 있지만 Promise나 Async를 이용하면 더 편하게 구현할 수 있습니다.

 

 

 

참고자료

https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/

 

자바스크립트 비동기 처리와 콜백 함수

(중급) 중급 자바스크립트 개발자가 되기 위한 자바스크립트 비동기 처리와 콜백 함수 이해하기. 콜백 지옥과 해결 방법 등

joshua1988.github.io

 

반응형

댓글