FRONTEND/JavaScript

(Promise, async & await) - 콜백헬을 피해서...

MarkLEE 2021. 5. 31. 16:18

앞서 우리는 비동기적인 것을 제어하는 방법으로 콜백함수를 살펴 보았다. 

하지만, 이렇게 작성할경우, 코드의 이해가 매우 힘들어 질수 있다는 단점이 있었다. 

 

이러한 콜백헬을 극복하기 위해서 나타난 개념이 바로 Promise이다. 

 

Promise

var Promise: PromiseConstructor

new <any>(executor: (resolve: (value: any) => void, reject: (reason?: any) => void) => void) => Promise<any>

✔️ 위에서 볼 수 있듯이, Promise는 첫번째 인자로 executor함수를 받게 된다.

✔️ JavaScript에 내장되어 있는 object

☑️ "성공한 상태(State)" 인지, "실패한 상태(State)" 에 대한 이해가 필요. 

☑️ 정보를 제공하는자(Producer)와 정보를 소비하는자(Consumer)로 구분해서 이해하자

☑️ Promise의 State단계?   "pending(state)" ➡ "resolve(state)" or "reject(state)"

 

 

✔️ producer

앞서 말한 것 처럼, promise는 Array와 비슷하게 javascript에 내장되어 있는 object(Class)이다. 

☑️그러므로, 내장된 클래스를 사용하기 위해선 인스턴스를 만들 필요가 있다. 

promise라는 변수를 Promise인스턴스로 선언

☑️ 여기에서 중요한 것은,  이렇게 promise인스턴스를 만들게 되면, executor함수가 바로 실행이 된다는 점이다. (그러므로, 위의 예에서는, 바로 콘솔창에 'doing sth'이 출력되게 된다. )

☑️ 그리고 이렇게 실행된 executor함수는 앞서 설명한 것 처럼 pending state를 지나, 두가지 중 하나의 state(resolve, reject)를 가지게 된다. 

 

☑️ 위의 예에서, const promise는 reslove상태 일때, 'Mark'라는 값을 전달하게 되고, 실패한 경우(reject state)에는 Error클래스를 불러와 'no network'를 출력하게 된다. 

☑️ 자, 이렇게 어떻게 promise를 선언하는지 producer 측면을 살펴 보았다. 실제로 그렇다면 사용은 어떻게 할 수 있을까?

 

✔️ consumer

☑️ 프로미스객체는 .then을 통해서 사용이 가능하다. 

 위에서 선언한 프로미스 객체를 이용하는 모습

☑️ 위에서 resolve로 전달한 'Mark'라는 값은 value로 전달되게 되고, 이것이 console에 출력되게 된다.

☑️ finally는 regardless state is resolve or reject, it will be always called.

☑️ catch is used for when the state is reject;

☑️ then is used for when the state is resolve;

 

✔️ promise chaining

☑️ promise .then에서 우리는 단순히 콜백함수를 실행 시킬수 있을 뿐만 아니라, 다른 new Promise를 return 할 수도 있다.

 

☑️ resolve에서 1을 저장, 첫번째 num에 전달해 주게 되고, 

☑️ 3번째 num에 6이 저장되게 된다. 그리고 이 값을 1초 뒤에 실행 되는 setTimeout함수에 넣어 실행하게 되면, resolve에는 -4라는 값이 저장. 

☑️ 마지막 num에서 -4가 콘솔에 출력되게 된다. 

 

 

✔️ promise chaining  사용에 있어서 tip!!

☑️ 위와 같은 코드를 통해, 우리는 3020이라는 숫자가 출력될 것이라는 것을 알 수 있다. 

☑️ 이를 좀 더 간 결하게 표현 할 수 있을까? 우리는 then을 사용할때, 하나의 인자만을 받는다면, 생략할 수 있다. 그 예는 아래와 같다.