본문 바로가기

Development/Javascript

async/await로 Promise를 사용하면서 reject을 try/catch로 잡을 때 주의할 점

728x90

문제의 시작
rxjs를 써보려다가 아직은 숙달되지 않아서 다시 Promise 기반으로 로직을 바꿨는데 rxjs 로직이었다가 Promise로 바꿔서 그런지 Promise가 배열로 생기는 문제가 발생하였다. 다행히도 Promise에는 mergeAll()과 비슷한 Promise.all()이 있기 때문에 여러 Promise가 끝나는 시점에 한 번에 동작 시키는 것은 가능했지만 이상하게도 catch가 안 잡히는 문제가 있었다. jsfiddle을 통해 간단하게 구현하여 테스트 해보니 java의 Exception을 try/catch로 잡는 것처럼 잡아선 안 되는 거였다.

아래 먼저 작성했던 코드가 있다.

결과는 이렇게 나온다.

코드를 보면 알겠지만 함수에 의해  Promise 배열이 생성되고, Promise.all을 이용하여 실행시킨 뒤에 값을 리턴하게 만들고, 함수를 실행하는 쪽에서 try/catch로 reject을 잡으려고 했다. 하지만 catch가 제 역할을 하지 못 했다. 나는 원래 java 개발자여서 당연히 함수 밖에서도 잡을 수 있을 거라 생각한 내 잘못이었다. 다음 코드로 바꾸었더니 try/catch로 잡혔다.


해결


수정 결과는 이렇게 catch가 잘 잡힌다.

간단한 변경이지만 try/catch를 사용하려면 await가 어디에 걸려 있는가가 굉장히 중요하다. 분명 에러가 났는데 계속 진행이 되길래 무슨 문제인지 한참 찾았다ㅜㅜ


정리.
async/await가 비동기 프로그래밍에서 신세계 본점 수준의 복잡성을 줄여주는 엄청난 기법임은 틀림 없다. 하지만 아이러니하게도 이 기법을 사용하면 버그를 낼 확률을 높이는 것 같다. 너무 간단히 Promise를 사용할 수 있으니까 async/await를 빠뜨리고 타이밍이 어긋나는 문제가 발생하기도 한다. 숙달된 고수님들은 아니라고 하시겠지만 나 같은 범인들은 주의해서 코딩해야 한다.

추가.

순차적으로 Promise를 실행하고 싶은 경우는 reduce()를 이용하는 방법이 있는데 아래 주소로 가면 아주 자세히 잘 설명되어 있다. 덕분에 나도 잘 이해했다 ㅎㅎ

https://github.com/nhnent/fe.javascript/wiki/%23180:-reduce()-%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%B4-%EC%88%9C%EC%B0%A8%EC%A0%81%EC%9C%BC%EB%A1%9C-%ED%94%84%EB%9D%BC%EB%AF%B8%EC%8A%A4%EB%A5%BC-%ED%95%B4%EA%B2%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8F%99%EC%9E%91%ED%95%98%EB%8A%94%EA%B0%80%3F


반응형