우리가 뭔가를 약속한다는 건, 약속된 무언가를 지금 당장 하지는 않지만 나중에 꼭 하겠다는 의미를 담고 있죠. 자바스크립트에서 프로미스(promise)는 동기적으로 당장 처리하는 것이 아닌, 비동기적인 처리에 사용되는 객체입니다.
지난 콜백 글에서 살펴봤듯이 비동기적인 처리를 쉽게 이해할 수 있는 예시가 바로 카페에서의 주문과 음료 수령입니다. 음료를 마시기 위해 카페에서 주문을 넣었는데, 그 주문이 끝날 때까지 아무 것도 할 수 없다면 손님 입장에서나 카페 입장에서나 매우 비효율적이겠죠.
이처럼 어떤 실행이 완료되기까지 시간이 걸리거나, 아니면 당장 해야되는 일이 아니거나, 꼭 그렇지 않더라도 필요할 경우에 우리는 프로미스를 활용해 서버나 기타 다른 곳에 요청을 전달하고서 중단 없이 계속 코드를 실행할 수 있습니다. 그리고 프로미스로 전달한 요청은 요청이 처리되면 다시 돌아와 실행됩니다.
프로미스는 이런 비동기적인 처리를 조금 더 수월하게 할 수 있도록 고안되었습니다. 프로미스의 활용을 통해 우리는 콜백 지옥(callback hell)에서 벗어날 수 있고, 가독성이 높은 코드를 얻게 됩니다. 이는 당연히 생산성의 향상으로 연결되겠죠.
프로미스는 기본적으로 resolve 와 reject 라고 하는 2 가지 콜백 함수를 가지고 있습니다. resolve 는 프로미스가 정상적으로 이행될 때 동작하는 함수이고 reject 는 반대로 어떤 에러 상황에 마주했을 때 동작하는 함수죠.
왜 에러 상황에 대비해야 할까요? 에러가 발생하지 않도록 코드를 잘 짜야 하는거 아닐까요? 라는 질문이 들 수도 있습니다. 실제로 지금까지의 공부는 오롯이 잘 만들어 동작하기만 했으면 됐었으니까요. 발생할 수 있을 만한 에러 상황은 코드를 작성하기 전에 미리 대비하고, 코드가 실행되는 동안에는 에러가 발생하지 않아야 하는 것처럼 느낄 수도 있습니다.
여기에서 우리는 비동기의 장점 뒤에 가려진 아쉬운 점을 발견할 수 있습니다. 비동기적인 실행으로 끊김이 없는 흐름을 얻는 대신, 에러가 발생할 수 있는 가능성이라는 위험요소를 얻게 되는 건데요. 왜 그런지를 이해하기 위해 카페에서의 새로운 예시를 생각해보겠습니다.
2명의 직원이 일하는 카페라고 가정하겠습니다. 손님이 많아 한 직원은 주문을 받고 있고, 다른 직원이 음료를 전담해서 만들고 있습니다. 그러다가 주문한 내용이 제대로 전달되지 않아 실수로 다른 음료가 나왔습니다. 이런 경험 다들 한 번쯤 겪어보시지 않았나요?
비동기적인 상황은 지금의 런타임이 아닌 다른 환경과 연결되어 무언가를 요청하고 결과물을 받는 일련의 과정입니다. 따라서 아무리 한 쪽이 제대로 된 요청을 전달했다 해도, 이를 주고 받는 과정 속에서 예상치 못한 일들이 일어날 수 있게 됩니다. 주문을 받는 사람 입장에서는 받은 주문을 제대로 전달했으니 억울할 수도 있겠지만, 혼자 하는 일이 아니라면 늘 오류가 생길 수 있는 것과 비슷한 겁니다.
따라서 프로미스는 정상적으로 이행될 때 동작하는 resolve 와 에러에 마주했을 때 동작하는 reject 를 콜백 함수로 가지고 있습니다. 공식 문서는 Promise 가 대기(pending), 이행(fulfilled), 거부(rejected) 라고 하는 3가지 상태 중 하나를 가진다고 설명하는데요. 이행될 때는 resolve 가 반환되고 거부될 때는 reject 가 반환된다고 이해할 수 있겠네요.
글이 길어지는 거 보니 프로미스를 아직 충분히 녹여내지 못했다는 생각이 듭니다. 사실 프로미스도 당연히 공식 문서가 있습니다. 늘 그렇듯 활용 방법은 이런 공식 자료를 확인하는 게 가장 확실하겠죠.
하지만 개인적으로 프로미스는 공식 문서부터 시작하면 이해하기 어렵다고 생각합니다. 유튜브에 좋은 영상이 많이 있으니 차라리 유튜브로 기본 개념을 정리한 이후에 문서를 살펴보는 편이 좋은 것 같아요. 사실 제가 그냥 그랬다는 걸 말씀드리는 겁니다..ㅋㅋ
프로그래밍과 관련한 많은 선생님들이 유튜브에 상주하고 계신데요. 프로미스와 관련해서 개인적으로 제가 도움을 받았던 영상을 하나 소개해드릴까 합니다. 페어분의 소개로 알게 된 코드종 이라는 유튜버이신데 아쉽게도 지금은 활동하시는 건 아닌 것 같아요. 그래도 callback, promise, async/await, 그리고 예외 처리까지 쭈욱 정리되어 있이서 아마 이해하는 데 큰 도움이 되실 거라고 생각합니다.
많은 분들이 이미 아실 법한 드림코딩 엘리님도 JavaScript ES6 시리즈 영상으로 정말 꿀같은 강의 제공하고 계시니까요. 참고해보시고 많은 도움 얻으시길 바랍니다.