안녕하세요.
Hynn 입니다.
이번 포스팅에서는 Promise 객체에 대해서 알아보도록 하겠습니다.
Callback 지옥을 해결하기 위해서라고 했지만, JavaScript 에서 가장 많이 쓰이는 객체를 이해하면 보다 비동기를 효율적으로 처리할 수 있습니다.
시작해보도록 하겠습니다.
1. Promise 객체 알아보기
Promise 객체는 기본적으로 상태값을 가지고 있습니다.
이 상태는 3가지로 구분됩니다. 아래의 상태를 살펴보도록 하겠습니다.
- Pending - 대기 상태
- Fulfilled - 성공
- Rejected - 실패
Promise 객체는 기본적으로 비동기처리를 수행하면 Pending 이라는 대기중 상태를 갖습니다.
이 상태에서 작업을 수행하고 성공하면 Resolve 라고 하는 Fulfilled, 실패했을 경우 reject 라고 하는 Rejected 상태로 변하게 됩니다.
이를 이제 기초적으로 예제코드를 활용하여 살펴보도록 하겠습니다.
const verifyNumber = (number, resolve, reject) => {
setTimeout(() => {
if (typeof number === 'number') {
resolve(number >= 0 ? 'Positive' : 'Negative');
} else {
// Reject
reject('This is not a number');
}
}, 2000);
};
verifyNumber(
5,
(resolve) => {
console.log(resolve);
},
(error) => {
console.log(error);
},
);
이 코드를 구성하는 것을 살펴보면, 먼저 verifyNumber 라는 함수를 선언하고, 매개변수로, number, 그리고 promise 객체의 상태에서 설명한대로, resolve, reject 를 추가합니다.
그리고 나서, 조건문을 사용해서 typeof 로 데이터타입이 숫자형인지를 확인하고, 만약 맞다면, 삼항연산자를 사용하여 resolve 내의 숫자가 양수인지, 음수인지를 판단하는 코드를 작성합니다.
만약 숫자가 아니라면 reject 를 실행하도록 작성합니다.
코드의 지연시간은 2초를 설정합니다.
그리고 나서, 함수를 호출할때, resolve, reject 의 대한 영역을 코드로 구현합니다.
화살표 함수로 구현한 이 코드들은 각각 resolve, reject 에대한 처리를 담당합니다.
이렇게 실행하면 위의 예제코드는 5의 양수이므로, 결과가 "Positive" 가 출력되도록 구현됩니다.
이제 이를, Promise 객체로 변환해보도록 하겠습니다.
const isPositivePromise = (number) => {
const execute = (resolve, reject) => {
setTimeout(() => {
if (typeof number === 'number') {
console.log('Number is', number);
resolve(number >= 0 ? 'Positive' : 'Negative');
} else {
console.log('Number is', number);
reject('This is not a number');
}
}, 1000);
};
const asyncTask = new Promise(execute);
return asyncTask;
};
기존의 코드와 유사하지만 다르게 구현된 코드를 살펴보겠습니다.
함수 내의 number 인자를 받고, 그 안에 execute 를 추가로 선언하여 resolve,reject 를 받은 뒤, 비동기 작업을 수행합니다.
그리고 asyncTask 라는 변수 내에 new Promise(execute) 로 결과값을 Promise 객체로 담습니다.
그리고 난뒤 , asyncTask 를 반환합니다.
즉, asyncTask 가 Promise 객체를 생성하고, execute 를 담는 것이 됩니다.
이를 Console 로 출력해보면 "Promise { <pending> } " 이라는 형태로 출력될 것입니다.
이제 이를 활용하는 기초적인 방법은 아래와 같이 작성할 수 있습니다.
바로 "then" 메서드와, "catch" 메서드입니다.
기본적인 작성형태는 아래와 같이 이루어져 있습니다.
const res = isPositivePromise(10);
res
.then((res) => {
console.log('Result is', res);
})
.catch((err) => {
console.log('Error is', err);
});
response 를 의미하는 res 에 함수를 호출하고, 이를 점 표기법을 사용하여 then, catch 로 작성하는 방식입니다.
즉, then 에서는 정상적으로 수행되는 resolve, catch 는 reject 를 의미하는 error 를 처리하는 영역입니다.
이렇게 하면, 결과에 맞는 값이 출력됩니다.
2. async/await 사용하기
이러한 Promise 객체를 다루는 코드역시도 직관적으로 보여지지 않는 경우가 발생합니다.
이를 보다 직관적으로 사용하기 위해, async/await 를 사용하는 기본적 방법을 알아보도록 하겠습니다.
이는 Promise 객체를 보다 쉽게 다루게 해주는 기능이라고 이해하시면 되겠습니다.
먼저 예시 함수를 하나 만들어 보겠습니다.
const delay = (ms) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms);
});
};
const helloAsync = async () => {
return delay(3000).then(() => {
return 'Hello Async';
});
};
비동기 함수를 작동하기 위해 위의 예제코드를 하나 만들었습니다.
위의 비동기 코드는, setTimeOut 을 매개변수로 받아, 동작하도록 구현했습니다.
이 경우 reject 는 고려하지 않고 resolve만 처리하도록 하였고, helloAsync 에서 delay 를 매개변수로 받아 then 메서드를 사용하여 동작하도록 처리했습니다.
하지만 async/await 의 기본적인 개념은 아래의 한줄로 정의할 수 있습니다
" 비동기코드를 동기코드처럼 동작하도록 도와주는 method"
async 와 await 은 항상 세트로 동작합니다.
async 의 주된 역활은 async 가 붙어있는 함수는 항상 결과값을 Promise 객체로 반환합니다.
즉, 결과가 Promise 객체가 아니더라도 JavaScript 에서는 이를 Promise 객체로 감싸서 값을 반환합니다.
await 은 항상 async 로 동작하는 함수 내에서만 사용할 수 있습니다.
단어의 뜻 그대로, Promise 객체의 Pending 상테에서 Fulfilled, rejected 의 결과를 기다리며, 결과가 나오면 값을 반환합니다. 당연히, rejected 가 발생하면, 이는 예외를 발생시키게 됩니다.
이를 사용하면 then, catch 보다 더 간결하게 비동기 함수를 동작할 수 있습니다.
이 async, await 은 실제 작은 페이지 구현을 하면서 보다 여러가지로 다루어보도록 하겠습니다.
감사합니다.
'개발공부일지 > React' 카테고리의 다른 글
React - State & Props 알아보기 (0) | 2023.08.10 |
---|---|
React - 왜 React 가 대세가 되었을까? (0) | 2023.08.09 |
React - JavaScript 응용하기 ( 동기 & 비동기) (0) | 2023.08.06 |
React - JavaScript 응용하기 (스프레드 연산자) (0) | 2023.08.06 |
React - JavaScript 응용하기 (비 구조화 할당) (0) | 2023.08.05 |
댓글