[Javascript] 2. 비동기처리 Promise와 async/await
in Javascript on Javascript 개발 기록
비동기처리 Promise와 async/await
콜백함수와 Promise
ES6 기반에서 개발하다 이전 프로젝트에서 ES5 환경에서 여러 오픈 js 라이브러리들을 적용해서 개발하다 보면 콜백함수가 너무 많아져서 콜백지옥이 발생하거나 비동기처리(자바스크립트 로직 실행 순서)
를 제어하기가 어려워진 경험을 겪다보니 간단하게 Promise와 async/await 에 대한 정리이다.
- 동기 : 요청을 보낸 후 해당 응답을 받아야 다음 동작을 실행
- 비동기 : 요청을 보낸 후 응답에 관계 없이 다음 동작을 실행
- 비동기처리 : 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고, 순차적으로 다음 코드를 먼저 실행하는 자바스크립트의 특성(
싱글 스레드, 콜스택
)
비동기처리
아래와 같이 서버 요청 후에 서버에서 처리하는 동안 기디라지 않고 다음 코드를 자바스크립트는 실행하기 때문에 원치 않은 답이 상황이 온다.
function getData() {
let retData;
$.get('url주소/products/1', function(response) {
retData = response;
});
return retData;
}
//서버에 api요청 후에 기다리지 않고 코드 실행
console.log(getData()); // undefined
Promise
Promise는 비동기 연산이 종료된 이후의 결과값이나 실패 이유를 처리하기 위한 처리기를 연결할 수 있도록 합니다. 마치 동기 메서드처럼 값을 반환할 수 있다
프로미스의 3가지 상태(states) = 처리 과정
- 대기(pending): 이행하거나 거부되지 않은 초기 상태.
- 이행(fulfilled): 연산이 성공적으로 완료됨.
- 거부(rejected): 연산이 실패함.
아래 콜백함수와 Promise 2개의 코드는 동일한 처리이다.
콜백함수
// 콜백 함수
function getData(callbackFunc) {
$.get('url주소/products/1', function (response) {
if (! response) {
console.log('Request is failed');
}
callbackFunc(response); // 서버에서 ajax 처리 후 callbackFunc() 호출
});
}
getData(function (data) {
console.log(data);
});
Promise
function getData() {
return new Promise(function (resolve, reject) {
$.get('url주소/products/1', function (response) {
if (! response) {
reject(new Error('Request is failed'));
}
resolve(response);
});
});
}
// Fulfilled 또는 Rejected의 결과 값 출력
getData().then(function (data) {
console.log(data);
}).catch(function (err) {
console.error(err);
});
webpack 등을 이용해서 ES6 개발환경이면 상관없지만, ES5 개발 환경에서 IE에서는 Promise 를 지원안해준다. IE Promise polyfill 로 검색해서 바벨에서 지원하는 라이브러리를 import해서 개발해야한다. 역시 좋은 곳에서 개발하는게 좋다.
async/await
async/await 접해보면 javascript가 왜 뜨는지 알 수가 있다. 비동기처리를 위한 콜백함수 패턴의 단점을 커버해서 개발하기도 편하고 코드 품질도 좋아지는게 느껴진다. 위에 콜백함수나 프로미스로 이용한 코드보다 더 간결하고 가독성이 좋다.
async/await
위에 있는 코드와 동일하다. async/await로 동기처리 해주며, async/await 를 없애면 !!가 있는 주석 라인의 response는 undefined가 출력 된다.
async function getData(callbackFunc) {
let response = await $.get('url주소/products/1');
if (! response) {
console.log('error');
}
console.log(response);//!!
callbackFunc(response);
}
다른 예제 코드
function getData() {
let response = await $.get('url주소/products/1');
//...코드
return response;
}
async function fnEmployee () {
let ret = await getData();
if (! ret) return;
//...코드
}
다른 예제 코드
var isValid = async function () {
var isBln = false;
await this.fnValid.then((ret)=> {
isBln = ('Y' == ret);
}, isBln);
return isBln;
}