JavaScript - Promise 비동기 처리하기
Promise 비동기 처리 간편하게 하기
프로젝트를 계속 진행하면서 한 페이지 내에서 많은 api를 불러와야하는 경우들도 생긴다. 메인 페이지를 구성해야하는데 계속 undefined가 뜨길래 왜 그런가 싶었는데 비동기 처리를 해주지 않아서 생긴 일이였다.
비동기의 장점은 확실히 한 api를 불러오는 동안 다른 작업을 수행할 수 있으니 수행 시간이 줄어든다는 것이다. 예를 들어 한 페이지 내에서 5개의 api를 불러와야하는데 그걸 다 끝날때까지 기다려야한다면 생각만해도 끔찍하다 ㅋㅋㅋㅋㅋㅋ 나같은 경우에는 작은 프로젝트라 상관없지만 실무에 들어가서 기다려야된다 생각하면 클라이언트 입장에서는 그 웹사이트에 들어가고 싶지않을 것 같다.
반면에 단점은 동기식 처리에 비해 설계가 복잡하다. 흔히 말하는 콜백지옥에 빠질 수 있다는 것이다
그렇게 되면 유지보수하기에도 쉽지 않고 가독성도 좋지않다.
이러한 단점을 상쇄하기 위해 나온 것이 바로 Promise구문이다!
Promise 역시 자바스크립트의 객체 중 하나인데, 비동기적으로 실행하는 작업의 결과를 객체화 시킬 수 있다! Promise의 가장 큰 장점이라고 하는데 앞으로 공부하면서 이게 왜 장점인지 더 생각을 해봐야 될 것 같다.
Promise 객체 생성하기
Promise는 객체이므로 생성자 함수와 동일하게 객체 구성이 가능하다.
//Promise 객체 만드는 순간 pending상태로 들어간다.
new Promise(
/* excutor */
(resolve, reject) => { ... });//pending
const p = new Promise((resolve, reject) => {
/* pending상태 */
setTimeout(() => {//일정상태 시간 이후에 실행하게 함
// fullfiled 상태(이행), 함수 안의 처리가 끝났을 때 호출하는 콜백 함수이다.
// 어느값이나 인수로 넘길 수 있다.
console.log('a');
resolve();
// 함수안의 처리가 실패햇을 때 실행되는 콜백함수
// 어느 값이나 인수로 넘길 수 있지만 주로 오류 메세지를 인자로 사용한다.
reject();
}, 1000)
});
p.then(() => {
/* callback */
console.log('1000ms후에 fullfilled')
// resolve 된 이후에 실행되는 공간
})
[ 결과 ]
- 1초 후에 a가 먼저 출력된 후에 콜백 함수가 실행된다.
- Promise 객체 안에 인자로 넘긴 setTimeout으로 이루어진 부분이 비동기가 실행되는 곳이다.
- resolve를 호출해서 Promise 처리 종료 : resolve 함수는 Promise를 종료시킴
Resolve/ Reject 메소드 알아보기
var promise = new Promise(function (resolve, reject) {
setTimeout(function () {
var name = prompt("이름을 입력하세요");
resolve(name);
}, 1000);
});
promise.then(function (name) {
console.log("안녕하세요, " + name + " 님!");
});
[ 결과 ]
- 1초 뒤에 prompt가 실행되고 resolve인자로 입력값을 넘긴다.
- then은 promise가 성공했을 때 실행되는 콜백 함수이므로 콘솔에 해당 name이 출력된다.
var promise = new Promise(function (resolve, reject) {
setTimeout(function () {
var n = parseInt(prompt("10 미만의 숫자를 입력하세요."));
if (n <= 10) {
resolve(n);
} else {
reject(`오류: ${n}은 10이상입니다.`);
}
}, 5000);
});
promise
.then(function (num) {
console.log("입력하신 수는 " + num + "입니다.");
})
.catch(function (err) {
console.log(err);
});
[ 결과 ]
- reject역시 Promise를 종료시키지만, 실패 콜백 함수이다.
- then()메소드가 실행되지 않고 catch 메소드가 실행된다.
Promise를 반환하는 함수
function p() {
//함수의 실행과 동시에 프로미스 객체를 만들면서 pending이 시작되게 하기위해서
return new Promise((resolve, reject) => {
/* pending */
setTimeout(() => {
//일정상태 시간 이후에 실행하게 함
resolve(); //fullfiled 상태(이행)
}, 1000);
});
}
p.then(() => {
console.log("1000ms 후에 fullfilled 됩니다.");
});
JSFiddle에서 실행해보기
(위의 예제들과 크게 다르지 않으나 함수를 사용하여 return 값이 Promise라는 것을 이용해서 함수에 인자를 넘겨 가독성을 높일 수 있는 것 같다.)
Promise가 어떻게 돌아가는지 약간 뜬구름 잡는 느낌으로 알고 있었는데 확실히 어떻게 돌아가는 지는 잡힌 것 같다. 하지만 막상 코딩을 하다보면 또 헷갈린다구 ㅠㅠ 비동기 파트 다 끝나면 현재 진행중인 프로젝트를 조금 수정하던 토이프로젝트를 진행하던 직접 코드를 좀 많이 만들어봐야할 것 같다.
참고 문서