[JavaScript]Promise
안녕하세요? "태민"입니다.
오늘은 ES6에 새로 추가된 기능 Promise에 대해서 포스팅하려고 합니다.
제가 프로젝트를 진행하면서 Axios를 이용해 비동기통신을 구현했습니다.
Axios도 Promise의 구조를 이용해서 구현된 거라 알고 있는데요.
여러 통신을 구현하고자 할 때, Promise.all function을 사용한 경험이 있습니다.
이때 resolve나 reject같은 개념들을 확실히 하지 않은 거 같아서 포스팅합니다.
1. 비동기 처리 모델
일단 비동기 처리 모델에 대해서 알아야 할 것 같습니다. 비동기 처리모델이랑 어떤 Task가 발생되었을 떄 현재 실행중인 Task를 멈추지 않고 병렬로 실행되는 것을 말합니다.
데표적인 예로 setTimeout function이 있습니다. 예제와 함꼐 살펴봅시다.
console.log(a) // 0
setTimeout(function(){
a += 1
},3000) // 3초뒤에 함수를 실행하게 됩니다.
console.log(a) // 0
setTimeout function은 비동기 함수입니다. 그러니 콜백함수가 실행될때까지 3초를 기다리지 않고, 바로 마지막줄이 실행됩니다. 즉, setTImeout은 블로킹하지 않고, 병렬로 실행되고 있다는 뜻입니다. 그렇기 때문에 비동기실행이 끝나는 시간에 어떤 동작을 수행하려면 callback함수가 필요합니다. 하지만 callback 함수를 남용하다 보면 callback hell에 빠지게 되고, 개발자 코드를 해석하기 어려워질 정도 코드가 난해해집니다.
asyncFunction1(function(input, result1) {
asyncFunction2(function(result2) {
asyncFunction3(function(result3) {
asyncFunction4(function(result4) {
asyncFunction5(function(output) {
// finally, do something...
});
});
});
});
});
위의 코드는 callback hell을 표현한 코드입니다.
2. Promise
2-1. 들어가기
위의 callback hell을 해결하거나 비동기처리방식에 좀 더 유연하게 대처하고 싶을 땐 Promise 사용하시면 됩니다. 그럼 Promise의 구조에 대해서 알아봅시다.
function test(){
return new Promise(function(resolve, reject) {
$.get(url, function(response) {
if(성공)
resolve(response);
else
reject(response)
});
});
}
test().then(function(response){
console.log(response)
},
function(response){
console.log(response)
})
- Promise는 resolve와 reject 라는 함수를 가지고 있습니다.
- resolve가 실행될 때는 then의 첫번째인자에 있는 함수가 실행되고,
- reject가 실핼될 때는 then의 두번째인자에 있는 함수가 실행됩니다.
2-2. error 처리
test1()
.then(function(response){
console.log(response)
},function(response){
console.log(response)
})
test2()
.then(function(response){
console.log(response)
}
.catch(function(response) {
console.log(response)
}
- test1()에서 reject가 실행될 때는 then의 두번째인자의 함수가 실행됩니다.
- test2()에서 reject가 실행될 때는 catch의 함수가 실행됩니다.
- catch는 뭘까요? catch는 error를 처리할 때 좋습니다. 특히 catch는 then에서 발생하는 error까지 처리해주기 때문에 then에서 reject를 처리하기보다는 catch에서 처리하길 권장드립니다.
2-3. 프로미스 체이닝(callback hell 해결하기)
위에서 callback hell이라는 말을 설명드렸습니다. 함수안에 함수가 반복되는 구조로 코드의 가독성이 떨어지고, 재활용하기에도 무척이나 까다로웠습니다. 프로미스는 이를 해결할 수 있습니다. 간단하게 원리를 도식화해 보았습니다.
한눈에 보아도 Promise를 사용한 그래프가 한눈에 구조를 파악하기 쉽습니다. 지금은 callback함수를 3개밖에 사용하지 않았지만, 함수의 갯수가 늘어나면 늘어날수록 더욱 더 빛을 발할 겁니다.
여담
막연히 Vue.js에서 Axios를 사용하다가 자연스럽게 터득한 Promise이라 이런 이점이 있는 줄 몰랐습니다. 비동기함수를 Axios외에 비동기 함수를 잘 쓰지 않으니 Promise의 이로운 점을 체득하기 어렵지 않았나 싶습니다. 예전에 Web기술을 배우면서 한 강의를 들은 적이 있습니다. 그 깅의에서 오로지 servlet으로만 웹을 구성한 적이 있었는데 이런 힘든 경험 후, MVC패턴을 이용한 Spring FrameWork를 사용했을 땐 얼마나 편했는지 모릅니다. 아마 이러한 기술도 나중에는 더 발전해서 나때는 이러이러해서 힘들었는데 발전됐구나! 라고 말할 날이 있겠죠?
안녕하세요? "태민"입니다.
혹시 틀린 내용이 있으시거나 추가하고 싶은 내용이 있으시면 댓글로 남겨주세요!