개발 공부/JavaScript 공부

[JavaScript] 프로미스(Promise)

종범2 2020. 3. 29. 13:16

비동기 함수를 사용할 때 성공한 경우와 실패한 경우에 따라 코드를 작성해야 하는 경우가 많다. 이때 가독성이 매우 떨어지는 코드를 작성하게 된다. 예를 들어 다음과 같은 testLuck이라는 이름의 비동기 함수가 존재한다고 생각해보자.

 

이 함수는 비동기적으로 1초후에 각각 1/2의 확률로 isErr을 true로 저장하거나 false로 저장하여 callbackFunc 함수를 호출한다. 운이 좋으면 isErr가 false가 되고 운이 나쁘면 isErr가 true가 된다는 의미를 담아 예시로 함수를 작성하였다. 이제 이 비동기 함수를 사용하는 코드를 작성하겠다. 이때 콜백 함수를 여러 번 호출하면 위에서 언급한 가독성이 떨어지는 코드를 작성하게 된다.

 

이 코드는 testLuck이라는 함수를 첫 번째로 호출하고, 만약 err가 false라면 testLuck을 두 번째로 호출하고, 이번에도 err가 fasle라면 testLuck을 세 번째로 호출하고, 역시 에번에도 err가 false라면 lucky라는 문자열을 호출하는 코드이다. 1/2의 확률로 isErr가 false가 되기 때문에 1/8의 확률로 성공하게 된다 (엄밀하게 1/8인지는 따지지 않겠다).

 

이런 식으로 콜백을 인자로 받는 비동기 함수를 계속해서 호출하게 되면 코드의 가독성이 매우 떨어지게 된다 (실제로 콜백을 인자로 받는 비동기 함수는 매우 많다). 만약 testLuck이라는 함수를 더 실행하고 싶거나 또 다른 비동기 함수를 실행하고 싶다면 코드는 더더욱 알아보기 힘들어진다. 성공했을 때의 경우만 중요하다면 일일이 에러 처리를 하기도 귀찮다.

 

이를 해결하기 위해 프로미스가 등장한다. 결론부터 말하면 프로미스를 사용하여 비동기 함수를 정의하면 나중에 이 비동기 함수를 사용할 때 코드가 간결해진다. 프로미스 (Promise)는 비동기 작업이 성공했을 때의 결과와 실패했을 때의 결과를 나타내는 객체이다. 프로미스를 선언할 때는 함수를 인자로 전달해야 하는데, 이 함수는 두 개의 인자를 받는 함수이다. 첫 번째 인자는 성공했을 경우에 실행할 함수이고 두 번째 인자는 실패했을 경우에 실행할 함수이다. 위에서 작성한 testFunc 함수를 프로미스를 반환하는 함수로 바꾸고 이때 코드가 어떻게 간결해지는지 보자.

 

promiseTestLuck은 프로미스를 반환한다는 점을 제외하면 testLuck과 같다. 프로미스 내부에서는 각각 1/2의 확률로 성공하는 경우의 함수를 호출하거나 실패하는 경우의 함수를 호출한다. 이제 이 프로미스를 반환하는 콜백 함수를 사용해보자.

 

코드가 훨씬 간결하다. 위의 경우처럼 세 번 promiseTestLuck 함수를 호출하였다. 프로미스에는 then과 catch라는 함수가 존재한다. 각 함수는 콜백 함수를 인자로 전달받는다. 프로미스 내부에서 성공하는 경우의 함수를 호출하면 then에서 전달한 콜백 함수가 실행되고, 프로미스 내부에서 실패하는 경우의 함수를 호출하면 catch에서 전달한 콜백 함수가 실행된다. promiseTestLuck라는 함수를 세 번 연속 호출하기 위해서는 다음과 같이 promiseTestLuck이 반환하는 프로비스를 반환하고 반환된 프로미스의 then 함수를 사용한다. then 함수를 호출하면서 한 번이라도 프로미스 내부에서 실패한 경우의 함수를 호출하면 이후의 모든 then 함수를 생략하고 catch 함수를 실행한다.

 

같은 기능을 하는 코드이지만 프로미스를 반환하는 비동기 함수를 사용하면 그 콜백 함수를 사용할 때 코드가 간결해진다. 요즘은 많은 비동기 함수가 프로미스를 반환하도록 작성되고 있는 추세이기 때문에 위의 코드처럼 직접 함수를 프로미스로 수정하는 일은 적다고 한다. 하지만 then과 catch를 이용하여 프로미스를 어떻게 사용하는지는 꼭 알 필요가 있다.

 

참고자료

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

 

Promise

The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.

developer.mozilla.org

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise

 

Promise

Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.

developer.mozilla.org