카테고리 없음

비동기처리

개발하는 가오나시 2024. 6. 3. 11:09

최근 면접을 자주 보면서 받았던 질문에 Promise객체에 대한 질문이 종종 있었다. 그 중에 Promise객체에 async/await문법을 적용하지 않으면, try/catch문에서 에러를 처리할수 있을 까요? 없을까요? 이런 질문이 있었다.

 

물론 제대로 대답 못했다. 했으면 이 글을 안썼겠지

 

그럼 알아보자 먼저 Promise이다.

 

기존의 비동기 코드는 콜백함수의 향연이었다.

 

자바스크립트의 동작방식을 보면, 비동기 코드는 실행되면 콜 스택에 들어갔다가, 이벤트 루프에 의해서 콜백함수가 태스크 큐에 들어가고 응답에 따라 혹은 타이머에 따라 이벤트 루프가 콜 스택이 비었을 때 콜백함수를 콜 스택에 넣어준다. Promise객체가 없을 때엔, 비동기 요청의 상태를 알 수 가 없으니 콜백함수에서 각 상태에 따라 또 콜백 콜백 콜백 이런 패턴이 반복되다 보니 > 이런 구조의 함수가 만들어 진다.

 

이렇게 복잡한 코드의 문제는 언제나 알아보기 어렵다 이다. 알아보기 어려우니 버그 찾기도 힘들고, 어드 콜백에서 에러가 났는지 에러 처리도 복잡해지는 것이다. 이런 단점을 극복하기 위해서 ES6에서 Promise객체가 등장한다.

 

Promise객체는 콜백 함수 패턴을 메소드 체이닝이라는 이쁜 패턴으로 승화했다. then.catch.finally 메소드를 활용해서 콜백함수에서 하기 복잡했던 에러 처리 라던지 가독성이 떨어지는 코드들이 이쁘게 정리되게 된다.

 

하지만 인간의 욕심은 끝이 없다. Promise로 결국 비동기 코드이기 때문에 실행시점이 불명확하다. 코드의 모든걸 컨트롤 하고 싶어하는 개발자는 결국 이 비동기도 동기처럼 동작하게 만들어 낸다.

 

그래서 es8에 async/await 문법이 등장한다.

 

async await문법의 등장으로 Promise를 동기적인 코드 처럼 사용하게 되었다. 이에 따라 es3에서부터 존재했던 에러잡는 문법인 try/catch문법을 활용해서 에러를 처리하게 된다. 

 

여기까지가 callback-Promise-async/await의 대략적인 흐름이다. 그럼 처음 문제로 돌아와서 Promise에 await안쓰면 try/catch에서 에러를 못잡나? 라는 지점으로 돌아오게 되면, 일단 정답은 못잡는다 이다. try/catch는 동기식 코드의 에러를 잡기위한 문법이다. 때문에 try/catch문이 콜 스택에 들어가서 내부 함수가 다 실행되면 try/catch문도 콜스택에서 나와버리니 이벤트루프가 나중에 전달한 콜백에서 일어난 에러를 잡아줄 코드가 없다.( 라고 나는 이해를 했다.)

 

애초에 동기 코드의 에러를 잡기 위한 문법이니까 async await을 사용하지 않은 Promise의 에러를 잡으려는 행동은 try/catch의 취지에 맞지 않은 것이기도 하니까 말이다. 결론은 async await을 사용하지 않으려면 Promise의 catch메소드에서 에러처리를 해줘야한다.