프로미스(Promise)
프로미스는 콜백 패턴이 가진 단점들을 보완하며 비동기 처리 시점을 명확하게 표현할 수 있다는 장점을 가지고 탄생하였다.(콜백을 예측가능한 패턴으로 사용할 수 있게 한다) → Promise를 사용하면 비동기 작업들을 보다 쉽게 구현 및 관리할 수 있다(콜백함수에 대한 자세한 내용은 이곳에서 확인가능하다.)
프로미스는 자바스크립트 비동기 처리에 사용되는 객체이다.
- 비동기 처리 : 특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 자바스크립트의 특성
- ES6에 도입 → 그럼 그전에는 비동기 처리를 어떻게? → 콜백함수로 비동기 처리를 할 수 있다. 그러나 익명함수로 콜백함수를 전달하는 과정이 반복되어 코드의 가독성이 떨어지고 콜백지옥 현상이 발생하는 문제 있음
Promise 객체는 자바스크립트에서 비동기적인 작업을 처리하는 데 사용되는 객체이다. 비동기적인 작업이란, 작업이 바로 결과를 반환하지 않고, 시간이 걸리거나 외부 요인에 의해 결과가 나중에 반환되는 작업을 말한다. 예를 들어, 파일을 읽거나 네트워크 요청을 보내는 등의 작업이 비동기적인 작업에 해당된다.
프로미스의 생성
Promise 객체는 new Promise()로 생성 → Promise 생성자 함수를 통해 인스턴스화
Promise 생성자 함수는 비동기적인 작업을 수행하는 콜백함수를 인자로 받고 이 콜백함수는 resolve와 reject 두 개의 함수를 인자로 받는다.
- resolve: 비동기적인 작업이 성공적으로 완료되었을 때 호출
- reject: 비동기적인 작업이 실패했을 때 호출
✏️ 비동기 함수 내에서 Promise 객체를 생성하고 그 내부에서 비동기 처리를 구현한다. 이때 비동기 처리에 성공하면 resolve 메소드를 호출한다. 이때 resolve 메서드의 인자로 비동기 처리 결과를 전달한다.
프로미스의 후속 처리
Promise로 구현된 비동기 함수는 Promise 객체를 반환해야한다. 그렇기에 그 반환된 값(비동기 처리 결과 및 에러 메시지) 처리해야 하는데 Promise 객체는 then**()**과 catch() 메서드를 통해 성공 및 실패 시의 처리를 할 수 있다.
- then(): Promise 객체가 이행된 경우에 호출
- catch(): Promise 객체가 거부된 경우에 호출
이때 then()과 catch() 메소드는 각각 콜백 함수를 인자로 받는다. 즉, then()과 catch() 메서드는 콜백 지옥(callback hell)을 해결하는 방법 중 하나인 것이다.
ex) 카카오 소셜로그인을 위해 카카오인증서버에 토큰을 요청할 때 그 결과를 then으로 받고 catch로 에러처리를 한다
const response = await axios(
requestTokenToKakao
).then(res => res.data)
.catch(err => console.log(err));
Promise의 3가지 상태
상태 = 처리 과정
- Pending(대기): 비동기 처리 로직이 아직 완료되지 않은 상태
//아래와 같이 new Promise() 메서드를 호출하면 대기 상태가 된다
new Promise()
// new Promise()를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject이다.
new Promise(function(resolve, reject))
- Fulfilled(이행): 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
// 콜백 함수의 인자 resolve를 실행하면 이행 상태가 된다
new Promise(function(resolve, reject){
resolve();
})
function getData(){
return new Promise(function(resolve, reject){
var data = 100;
resolve(data)
})
}
getData().then
- Rejected(실패): 비동기 처리가 실패하거나 오류가 발생한 상태
// 콜백 함수의 나머지 인자 reject를 실행하면 실패 상태가 된다.
new Promise(function(resolve, reject){
reject();
})
- then() 메서드를 호출하고 나면 새로운 프로미스 객체가 반환된다!
프로미스 체이닝
프로미스의 또 다른 특징은 여러 개의 프로미스를 연결하여 사용할 수 있는 것이다. Promise.then()을 호출하면 프로미스가 반환되기에 당연히 또. then()을 호출할 수 있는 것이다.
앞의 글에서 콜백으로 작성했던 청소과정을 프로미스를 사용한 코드로 변환하고 프로미스 체이닝을 사용하여 추가적인 프로미스를 연결해보았다 → 건조기 돌린 이후에 빨래정리를 프로미스 체이닝을 사용하여 연결사용!
const runWashingMachine = () => {
return new Promise(resolve => {
console.log("세탁기를 돌리는 중...");
setTimeout(() => {
resolve(console.log('세탁기 작업 완료'));
}, 3000);
});
};
const runDryer = () => {
console.log("건조기를 돌리는 중...");
return new Promise(resolve => {
setTimeout(() => {
resolve(console.log("건조기 작업 완료"));
}, 2000);
});
};
runWashingMachine()
.then(runDryer)
.then(function(){
new Promise(resolve=>{
console.log("빨래 정리 및 접기")
setTimeout(()=>{
resolve(console.log("빨래정리 작업 완료"))
},1500)
})
})
마치며
지난번 자바스크립트의 비동기와 작업방식 중 콜백함수를 함께 알아보았고 이번에는 프로미스 객체를 살펴보았다. 비동기 작업은 보통 async / await를 주로 사용했었고 직접적으로 then으로는 몇 번? 정도 사용했었던 것이 기억났다. 다음에는 마지막으로 async/await를 알아보며 비동기 관련 글을 마무리하려 한다.
참조
https://inpa.tistory.com/entry/JS-📚-비동기처리-async-await
'TIL' 카테고리의 다른 글
async / await (0) | 2023.03.29 |
---|---|
동기 / 비동기 (0) | 2023.03.27 |
Libuv 라이브러리(feat. 이벤트 루프) - 3 (0) | 2023.03.24 |
V8엔진 구조 및 작동 방법 - 2 (0) | 2023.03.23 |
나는 왜 Node.js를 사용했을까? - 1 (0) | 2023.03.15 |