소개
자바스크립트 프로미스는 이해하기 어려울 수 있습니다. 그래서 저는 프로미스를 이해하는 방법을 적어보려고 합니다.
프로미스 이해하기
프로미스란 간단히 말해:
“당신이 아이라고 상상해보세요. 엄마가 약속하셨죠, 다음 주에 새 폰을 사주신다고.”
당신은 모릅니다 다음 주까지 그 폰을 받을지 말지. 엄마는 진짜로 새 폰을 사줄 수도 있고, 사주지 않을 수도 있습니다.
그것이 약속입니다. 약속에는 세 가지 상태가 있습니다. 그것들은:
- 대기 중: 당신은 모릅니다 그 폰을 받을지 말지
- 이행됨: 엄마가 기뻐하며, 당신에게 새 폰을 사줍니다
- 거부됨: 엄마가 슬퍼하며, 폰을 사주지 않습니다
프로미스 만들기
이것을 자바스크립트로 바꿔봅시다.
코드 자체가 상당히 표현적입니다.
아래는 일반적으로 프로미스 구문이 어떻게 보이는지 입니다:
프로미스 사용하기
이제 프로미스가 있으니, 사용해보겠습니다:
예제를 실행해보고 결과를 확인해봅시다!
데모: https://jsbin.com/nifocu/1/edit?js,console
Promise 연결하기
Promise는 연결 가능합니다.
예를 들어, 당신이 아이로서, 엄마가 새 휴대폰을 사주면 친구에게 약속하고 보여줄 것입니다.
이것은 또 다른 약속입니다. 이를 작성해 봅시다!
참고: 위의 코드를 아래와 같이 줄여서 작성할 수 있습니다:
Promise를 연결해 봅시다. 당신, 아이는 willIGetNewPhone
Promise가 끝난 후에만 showOff
Promise를 시작할 수 있습니다.
이렇게 하면 Promise를 연결할 수 있습니다.
약속은 비동기적이다
약속은 비동기적입니다. 약속을 호출하기 전과 후에 메시지를 기록해 보겠습니다.
예상되는 출력 순서는 어떻게 될까요? 다음과 같을 것으로 예상할 수 있습니다:
1. before asking Mom
2. Hey friend, I have a new black Samsung phone.
3. after asking mom
그러나 실제 출력 순서는 다음과 같습니다:
1. before asking Mom
2. after asking mom
3. Hey friend, I have a new black Samsung phone.
엄마의 약속(새 폰)을 기다리는 동안 놀이를 멈추지 않을 것입니다. 이것이 바로 비동기적이라고 부르는 것입니다: 코드는 결과를 차단하거나 기다리지 않고 실행됩니다. 약속을 기다려야 진행되는 모든 것은 .then
에 넣습니다.
다음은 ES5의 전체 예제입니다:
ES5, ES6/2015, ES7/Next의 Promises
ES5 – 대부분의 브라우저
데모 코드는 Bluebird promise 라이브러리를 포함한다면 ES5 환경(모든 주요 브라우저 + NodeJs)에서 작동합니다. 왜냐하면 ES5는 기본적으로 promises를 지원하지 않기 때문입니다. 또 다른 유명한 promise 라이브러리는 Kris Kowal의 Q입니다.
ES6 / ES2015 – 최신 브라우저, NodeJs v6
데모 코드는 ES6가 기본적으로 프로미스를 지원하기 때문에 바로 작동합니다. 또한, ES6 함수를 사용하면 화살표 함수로 코드를 더 간단하게 만들고 const
와 let
을 사용할 수 있습니다.
다음은 ES6 코드의 전체 예제입니다:
모든 var
가 const
로 대체되었고, function(resolve, reject)
는 (resolve, reject) =>
로 간소화되었습니다. 이러한 변경으로 인해 몇 가지 이점이 있습니다.
ES7 – Async/Await
ES7에서는 async
와 await
구문이 도입되어 비동기 구문을 .then
과 .catch
없이 더 쉽게 이해할 수 있게 되었습니다.
ES7 구문으로 예제를 다시 작성해 보겠습니다:
프로미스와 사용 시기
왜 프로미스가 필요한가? 프로미스가 없었을 때 세상은 어땠을까? 이 질문에 답하기 전에 기본부터 살펴보자.
일반 함수 VS 비동기 함수
두 가지 예제를 살펴보자. 두 예제 모두 두 숫자의 덧셈을 수행한다: 하나는 일반 함수를 사용하여 더하고, 다른 하나는 원격으로 더한다.
두 숫자를 더하는 일반 함수
두 숫자를 더하는 비동기 함수
일반 함수로 숫자를 더하면 결과를 즉시 얻을 수 있다. 하지만 원격 호출을 통해 결과를 얻으려면 기다려야 하며, 결과를 즉시 얻을 수 없다.
서버가 다운되거나 응답이 느려질 수 있기 때문에 결과를 받을지 여부를 알 수 없습니다. 결과를 기다리는 동안 전체 프로세스가 차단되지 않기를 원합니다.
API 호출, 파일 다운로드 및 파일 읽기는 수행할 몇 가지 일반적인 비동기 작업입니다.
비동기 호출에 프로미스를 사용할 필요는 없습니다. 프로미스 이전에는 콜백을 사용했습니다. 콜백은 결과를 받을 때 호출하는 함수입니다. 이전 예제를 수정하여 콜백을 허용해 보겠습니다.
후속 비동기 작업
숫자를 하나씩 더하는 대신 세 번 더하고 싶습니다. 일반 함수에서는 다음과 같이 할 것입니다:-
이렇게 콜백을 사용하면 다음과 같습니다:
데모: https://jsbin.com/barimo/edit?html,js,console
이 구문은 콜백이 깊게 중첩되어 있어 사용자 친화적이지 않습니다.
깊게 중첩된 콜백 피하기
프로미스는 깊게 중첩된 콜백을 피하는 데 도움이 될 수 있습니다. 같은 예제의 프로미스 버전을 살펴보겠습니다:
프로미스를 사용하면 .then
으로 콜백을 평평하게 만들 수 있습니다. 어떤 면에서는 콜백이 중첩되지 않아 더 깔끔해 보입니다. ES7 async
구문을 사용하면 이 예제를 더욱 향상시킬 수 있습니다.
옵저버블
프로미스에 안착하기 전에, 옵저버블
이라는 비동기 데이터를 다루는 데 도움이 되는 것이 등장했습니다.
옵저버블로 작성된 동일한 데모를 살펴보겠습니다. 이 예제에서는 옵저버블을 위해 RxJS를 사용하겠습니다.
옵저버블은 더 흥미로운 일을 할 수 있습니다. 예를 들어, delay
함수를 3초
동안 지연시키거나 특정 횟수만큼 호출을 재시도할 수 있습니다.
RxJs에 대한 나의 게시물 중 하나를 여기에서 읽을 수 있습니다.
결론
콜백과 프로미스에 익숙해지는 것은 중요합니다. 이해하고 사용하세요. 아직 Observable에 대해서는 걱정하지 마세요. 상황에 따라 세 가지 모두 개발에 영향을 줄 수 있습니다.
Source:
https://www.digitalocean.com/community/tutorials/understanding-javascript-promises