[JavaScript] 비동기 처리와 Promise
실무 오류 사건
데이터를 서버에서 불러와 화면에서 표시해야 하는데 데이터가 출력되지 않는 현상이 발생했습니다.
해당 값 확인 결과, undefined 로 출력되어 빈 값으로 출력되고 있었습니다.
데이터를 받는 곳의 로직 확인 결과, 비동기 처리 로직이었고 선임분들의 도움으로 Promise 객체를 사용하여 해결할 수 있었습니다.
그래서, 이번 포스팅은 실무 오류 사건에서 알게 된 자바스크립트의 비동기 관련 내용을 작성하려고 합니다.
제가 공부하면서 알게 된 내용임으로 정확하지 않을 수 있기 때문에 잘못된 부분은 댓글로 지적 부탁드립니다.
오류 발생한 로직
function itemGet() {
let getData;
$.get('https://store.com/item/1', function(res) {
getData = res;
});
return getData;
}
console.log(itemGet()); // undefined
위 코드는 Ajax 통신으로, 가게의 1번 물품을 가져오기 위한 예제 코드입니다.
이론상, 'https://store.com/item/1' 통신 결과를 res 인자에 담긴 후 getData 변수에 저장합니다.
하지만 itemGet() 함수를 호출하면 undefined 가 출력됩니다.
왜냐하면, $.get() 데이터를 요청하고 응답 값을 받을 때까지 기다리지 않고 return getData 를 실행했기 때문에 초기화되지 않은 undefined 가 출력된 것입니다.
즉, 위 로직을 비동기 처리했기 때문에 발생한 문제점입니다.
비동기 처리란?
위에서 언급한 비동기 처리란, 특정 로직이 끝날 때까지 기다리는 것이 아니라 이후의 로직을 실행하는 것입니다.
비동기 처리 사용 이유는?
요청한 데이터를 서버에서 응답을 전부 줄 때까지 마냥 기다릴 순 없기 때문입니다.
1건이 아닌 100만건의 데이터를 요청하고 받는다고 가정했을 때, 100만 건의 데이터 응답을 받기 위해서는 많은 기다림이 필요할 것입니다.
저는 비동기 처리를 카페 로 예를 들어 생각합니다.
카페에서 비동기 처리 방식이 아닌 주문받기/음료만들기/서빙 3단계를 손님 1명에게 서비스 후, 다른 손님이 받는다면 점심시간에 스타벅스 커피를 마시지 못할 것입니다.
하지만, 위 3단계는 현실 카페에서 비동기 처리 방식으로 이루어져 점심시간에 스타벅스 커피를 마실 수 있습니다.
비동기 처리 문제점
제가 경험한 문제점은, 위에 오류가 발생한 로직처럼 Ajax 통신에서 비동기 처리로 인한 데이터의 누락입니다.
이러한 문제점을 해결하기 위해서는 여러가지 방법이 있지만, 저는 Promise 로 아래와 같이 해결하였습니다.
Promise 해결 방법
function itemGet() {
return new Promise(function(resolve, reject) {
let getData;
$.get('https://store.com/item/1', function(res) {
getData = res;
});
// 데이터를 받으면 resolve() 호출
resolve(getData);
});
}
itemGet().then(function(res) {
console.log(res); // 'https://store.com/item/1' 통신 결과
});
오류가 발생하던 소스에 Promise 객체를 사용하여, 문제를 해결한 소스 코드입니다.
덕분에, 통신 응답 값을 출력할 수 있습니다.
Promise 란?
비동기 함수를 동기 처리하기 위해 고안한 객체입니다.
즉, 로직이 끝날 때까지 기다렸다가 성공-실패를 리턴하며 결과 값을 전달 받을 수 있습니다.
Promise 의 상태
3가지의 상태를 가지고 있습니다.
1. 대기(pending) : 이행하지도, 거부하지도 않은 초기 상태
2. 이행(fulfilled) : 비동기 처리의 연산이 성공적으로 완료 후 결과 값 반환을 해준 상태
3. 거부(rejected) : 비동기 처리의 연산이 실패한 상태
대기(pending)
new Promise() 메서드를 호출하면 대기 상태가 됩니다.
new Promise();
new Promise(function(resolve, reject) {});
이행(fulfilled)
resolve 인자를 실행하면 이행 상태가 됩니다.
new Promise(function(resolve, reject) {
resolve();
});
이행 결과 값은 then()을 사용하여 받을 수 있습니다.
itemGet().then(function(res) {});
실패(rejected)
reject 인자를 실행하면 실패 상태가 됩니다.
new Promise(function(resolve, reject) {
reject();
});
실패 결과 값은 catch()를 사용하여 받을 수 있습니다.
itemGet().then.catch(function(err) {});
여기까지...
실무에서 발생한 오류와 Promise 를 살펴봤습니다.
빈번하게 발생하는 오류라서 알아두면 좋다는 선임분의 말씀에 제 생각대로 정리해본 간단한 내용이었습니다.
추후에, 데이터 값이 정의되어 있지 않다면 비동기 처리 로직부터 확인해보아야 할 것 같습니다.
부족하지만 긴 글 읽어주셔서 감사합니다.
- 참조 -
https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://joshua1988.github.io/web-development/javascript/promise-for-beginners/