EtoC

비동기 일부 요청 실패 문제 : 해결(Promise.allSettled()) 본문

ETC/Error

비동기 일부 요청 실패 문제 : 해결(Promise.allSettled())

게리드 2024. 8. 24. 13:35

 

평소 잘 뜨던 학생대쉬보드 페이지가 다른 계정으로 접속하니 유튜브 API를 활용한 요소만 랜더링되고 나머지는 아무것도 뜨지않았다.

코드 정리를 한다고 axios 요청을 하나로 다 묶어버렸는데, 이게 문제가 된거같다.

 

코드를 확인해보니  확실히 가장 첫번째 fetch 요청이 실패해서 나머지 요청을 실행하지 않는거였다.

신규 회원이 가입했을경우 최근에 본 강의가 없어서 빈값이 들어왔을때 요청이 실패하는거라는 생각이들었고,

각 요청별로 예외처리를 하지않아서  줄줄이 실패하는 듯.

더보기
각각의 요청시 받아온 데이터의를 출력해보니 가장 첫번째인 recentLectureData에서 에러가 발생하는것을 확인.

 

왜 비동기 요청인데 첫번째 요청이 실패하니까 나머지도 호출이 안되나?

- async/await 비동기 코드를 동기코드처럼 작성할수 있어서 자주사용하고 있었는데, 잘 모르고 사용하고있었다.
- await을 사용하면 비동기 작업중 어딘가에서 에러가 발생하면 바로 catch쪽으로 throw되기때문에 다음 코드가 실행되지않는다.
- 그래서 try/catch를 각 요청마다 해야하는데 마감하면서 코드가 지저분해서 내가 다 합쳐버렸더니 이런 문제가 발생했다.

 에러핸들링 코드를 추가해서 실행해 보니 

 

받아온 데이터에는 아예 아무것도 뜨지않았고, 여전히 fetch는 실패;;

애초에 받아오는 데이터를 보니 아무것도 안떠서 백엔드 코드를 확인해봤다.

백엔드 코드에 맞게 예외처리를 해도 여전히 같은 문제가떴다.

이유를 모르겠네..이제 진짜 시간이없는데ㅜㅜ

 

데이터가 있으면 요청이 성공이니까 비동기요청이 일부 실패해도 나머지는 뜨게할 수 있지않을까?로 생각을 전환.

일단  Promise.all은 제외.

더보기
Promise.all은 왜 제외?

Promise.all()은 어떤 요청이 실패하면 전체 프로미스가 rejected 상태가 되어 다른 요청의 결과를 받을 수 없다.
즉, 현재와 똑같은 상태!

찾아보니 Promise.allSettled를 사용하면 어딘가에서 요청이 실패해도 나머지 요청의 결과를 받을 수 있다고한다. 

이제 실패해도 성공한 프로미스들은 다불러와지는데 이러면 내가 처음에 작성한 코드만큼 길어져서 맘에 안든다.

음 문제해결!

깔끔하게 역할별로 묶어줬다.

이제 발표할 수 있다!

 

 


Promise.allSettled()

allSettled 는 ES11에서 도입된 메서드인데, 모든 요청이 병렬적으로(동시에) 실행되지만, 각각의 요청은 독립적으로 처리된다.

Promise.allSettled()의 장점은 독립적으로 실행된다는 점이다.

독립적으로 실행된 요청의 상태는 fullfilled와 rejected로 나뉘고, 각 요청의 상태와 받아온 데이터 또는 에러를 포함한 배열을 반환한다.

이 배열은 성공했는지 실패했는지와 상관없이 모든 요청의 결과를 포함하며, 에러는 격리하여 다른 요청이 주단되지않도록 보장한다.

 

promise.allSettled는 일부 데이터 요청이 실패헤도, 성공한 데이터는 사용자에게 보여지게 해주기 때문에 좀 더 안전하고 

사용자가 페이지에 접속했을때  화면이 다 안나오는것과 하나만 안나오는거.. 이거 크다..

 


 

처음 개발 공부를 했을때는 Promise가 더 어렵고 then then 하는게 싫어서 잘 기피하는 경향이 있었는데

Promise로 속도 개선도 해보고 안되는 문제를 해결해보니 상당히 유용한거같다.