[JavaScript]Promise

ungnam·2023년 1월 30일

비동기 함수의 대표적 예시인 setTimeout 함수에 대해 생각해보자.

let timeout = setTimeout(() => {
	console.log('Hello world");
}, 1000);

위 코드는 1000ms 라는 조건 이후에 () => { console.log('Hello world"); } 부분이 바로 실행된다. 여기에는 문제가 있는데, 바로 비동기 처리 상태 및 처리 결과를 따로 저장할 수가 없다는 점이다.
timeout 변수는 고유한 타이머 ID를 반환하기 때문에 처리 결과를 보관하는 것이 아니다.

Promise

이러한 단점을 보완하기 위해 만들어진 것이 바로 Promise이다. Promise를 한 줄로 설명하자면 다음과 같다.

Promise는 실행은 하되, 결괏값을 나중에 쓸 수 있다.

const promise = new Promise((resolve, reject) => {
	setTimeout(() => {
    	resolve('fulfilled');
    }, 1000)
})

// ...
// do something...
// ...

promise.then((v) => console.log(v));	// fulfilled

Promise 생성자 함수는 비동기 처리를 수행할 콜백 함수인 resolvereject 함수를 콜백 함수의 인수로 전달받는다.
콜백 함수 내 비동기 처리가 성공하면 resolve 함수를 호출하고, 실패하면 reject 함수를 호출한다.

이렇게 resolve되거나 reject된 결괏값을 변수에 저장해놓고 있다가 나중에 사용할 수 있다는 점이 Callback과 다른 Promise의 특징이라고 할 수 있다.

Promise.all/Promise.allSettled

다음과 같이 여러 개의 데이터를 서버로부터 get하는 상황에 대해서도 생각해보자.

const p1 = axios.get('서버주소1');
const p2 = axios.get('서버주소2');
const p3 = axios.get('서버주소3');

Promise.all

Promise.all 메서드는 여러 개의 비동기 처리를 모두 병렬 처리할 때 사용한다.

Promise.all([p1, p2, p3])
	.then(console.log)
    .catch(console.error);

Promise.all 메서드는 모든 프로미스가 fulfilled 상태가 될 때 종료된다. 만약 프로미스 중 하나에 대해 에러가 발생한다면 이전의 모든 처리 결과를 무시하고 즉시 rejected 상태가 된다는 특징이 있다.

Promise.allSettled

Promise.allSettled 메서드는 Promise.all과 유사하나 성공/실패 여부와 관계없이 모든 처리 결과를 배열로 반환한다는 특징이 있다.

Promise.allSettled([p1, p2, p3])
	.then(console.log);
  • 프로미스가 fulfilled 상태인 경우 비동기 처리 상태를 나타내는 status 프로퍼티와 처리 결과를 나타내는 value 프로퍼티를 갖는다.
  • 프로미스가 reject 상태인 경우 비동기 처리 상태를 나타내는 status 프로퍼티와 에러를 나타내는 reason 프로퍼티를 갖는다.

따라서 Promise.allSettled 메서드 이용 시 실패한 것만 필터링해서 다시 요청을 보낼 수 있다는 장점 때문에 Promise.all 대신 사용할 것을 권장하고 있다.

profile
꾸준함을 잃지 말자.

0개의 댓글