개발/Javascript

비동기 요청 여러 개 보내고 전부 완료됐을 때 함수 실행하기 (Promise.allSettled)

duknock 2022. 8. 9. 14:08
반응형

제목이 길다.

 

말 그대로 비동기 요청 여러개를 보내고 모든 요청으로부터 응답이 도착했을때 실행해야 하는 함수가 있을때의 처리 방법에 관한 글이다.

 

물론 무식한 방법으로는 ajax(혹은 fetch...보통 익숙한 단어인 ajax라고 말하겠음)를 체이닝해서 동기적으로 처리하는 방법도 있긴하다.

 

fetch('url...')
.then(res=>res.json())
.then((data1)=>{
	fetch('url...')
	.then(res=>res.json())
	.then((data2)=>{
		fetch('url...')
		.then(res=>res.json())
		.then((data3)=>{
			fetch('url...')
			.then(res=>res.json())
			.then((data4)=>{
				console.log(data1);
				console.log(data2);
				console.log(data3);
				console.log(data4);
			})
		})
	})
})

(콜백지옥)

비동기 요청을 차례 차례 동기로 처리해버리는 기적의 코드다.

효율도 떨어지고 가독성도 안좋다.

 

그래서 Fetch 가 반환하는 Promise 객체에는 allSettled 라는 좋은 메서드가 존재한다.

Promise.allSettled() 메서드는 주어진 모든 프로미스를 이행하거나 거부한 후, 각 프로미스에 대한 결과를 나타내는 객체 배열을 반환합니다.

- MDN web docs

 

쉽게 말해서 '비동기 요청 다 끝나면 결과 준다' 이말이다.

 

Promise.all() 과 다른점은 Promise.all()은 하나라도 reject 되면 그 즉시 종료되지만 Promise.allSettled는 거부되든 말든 전부 이행한다는 것이다.

 

얘가 어떻게 동작하는지 예시로 보자면

let fetch1 = new Promise((resolve) => {
	setTimeout(() => {
		return resolve('fetch1 done');
	}, 1000);
});

let fetch2 = new Promise((resolve) => {
	setTimeout(() => {
		return resolve('fetch2 done');
	}, 1500);
});

let fetch3 = new Promise((resolve) => {
	setTimeout(() => {
		return resolve('fetch3 done');
	}, 2000);
});

let fetchArr = [fetch1, fetch2, fetch3];

async function test() {
	let results = await Promise.allSettled(fetchArr);

	if (results) {
		results.forEach((el) => console.log(el.value));
	}
}
test();

(async 와 await 정도는 미리 알아두자)

Promise 객체들을 배열에 담아서 Promise.allSettled()의 인수로 주면 모든 Promise가 이행된 후 배열로 결과값을 반환한다.

 

위 코드를 실행하면 fetch3이 완료되는 시점인 2초 후에 결과값이 콘솔에 찍힌다.


결과값

 

[
    {
        "status": "fulfilled",
        "value": "fetch1 done"
    },
    {
        "status": "fulfilled",
        "value": "fetch2 done"
    },
    {
        "status": "fulfilled",
        "value": "fetch3 done"
    }
]

fulfilled 는 정상적으로 이행됐다는 뜻이다.

만약 rejected가 뜨면 value 대신 reason이라는 프로퍼티가 생긴다. (실패 이유가 적혀있음)

 

얘를 잘 활용하면 Fetch 요청 여러개를 한번에 보낼 때 아주 유용하게 쓸 수 있다.

 

다만 최근에 추가된 신문법이라 구형 브라우저의 경우 폴리필을 해줘야한다.

반응형