Promise정리 [ State, Producer, Consumer(then, catch, finally), Promise Chaining, Error Handling ]
Promise란?
1. Promise는 비동기 작업에 대한 javascript 개체이다.
2. Promise는 State라는 상태값을 가지고 Promise 생상부분과 사용부분으로 나눌 수 있다.
3. 비동기 처리 동작은 기본적으로 callback과 동일하지만 단점(콜백지옥)을 보완했다.
1) State
state: pending -> fulfilled or rejected (보류 중 -> 이행 또는 거부됨)
pending 상태 = 값을 아직 알 수 없을 때 (data가 정확하게 할당되지 않았을 때 등)
fullfilled 상태 = 반환값이 할당되었을 때를 나타낸다.
rejected 상태 = 네트워크 에러같은 에러가 발생하였을 때를 나타낸다.
2) Producer, Consumer (생산자 vs 사용자) 아래 참고.
1. producer (생산자)
new Promise가 생성되면 executor(실행자)가 자동으로 실행된다
executor는 성공할 때 실행하는 resolve와 실패할 때 실행되는 reject가 존재한다.
resolve 실행 시
const promise = new Promise((resolve, reject) => {
// 네트워크를 통한 데이터 수신, 파일 읽기와 같은 시간이 걸리는 일을 수행한다.
console.log('doing something...');
setTimeout(() => {
resolve('success'); // 성공 시 호출
}, 2000);
});
promise.then((value) => {
console.log(value);
})
2초후에 Promise에서 성공할 때 호출하는 resolve가 실행된다.
출력값
success
reject 실행 시
const promise = new Promise((resolve, reject) => {
// 네트워크를 통한 데이터 수신, 파일 읽기와 같은 시간이 걸리는 일을 수행한다.
console.log('doing something...');
setTimeout(() => {
reject(new Error('no network')); // 실패 시 호출
}, 2000);
});
promise.then((value) => {
console.log(value);
})
2초후에 Promise에서 실패할 때 호출하는 reject가 실행된다.
출력값
- 에러 발생 시 예외처리를 하지 않아 에러 창이 나온다.
2. Consumers (사용자): then, catch, finally
promise
.then((value) => {
console.log(value);
})
.catch(error => {
console.log(error);
})
.finally(() => { console.log('finally'); });
then()는 promise가 정상적으로 수행되어서 resolve라는 콜백함수에서 전달한 값이 value의 parameter로 전달된다.
catch()는 실패해서 resolve 대신에 reject가 호출될 때 사용한다. (Error 핸들링 방법)
finally()는 성공여부에 상관없이 실행하는 함수이다.
출력값
// 성공시
"success"
"finally"
// 실패시
no networkError
"finally"
3. Promise chaining
const fetchNumber = new Promise(resolve, reject) => {
setTimeout(() => resolve(1), 1000);
});
fetchNumber
.then(num => num * 2)
.then(num => num * 3)
.then(num => {
return new Promise(resolve, reject) => {
setTimeout(() => resolve(num - 1), 1000);
});
})
.then(num => console.log(num));
위 코드는 2초 후에 5가 나온다.
여기서 알 수 있는 점은 then()은 값을 바로 전달할 수도 있고 Promise를 전달할 수도 있다.
4. Error Handling
const getA = () =>
new Promise((resolve, reject) =>
{setTimeout(() => resolve(`A`), 1000)
});
const getB = A =>
new Promise((resolve, reject) =>
{setTimeout(() => resolve(`${A} => B`), 1000)
});
const getC = B =>
new Promise((resolve, reject) =>
{setTimeout(() => resolve(`${B} => C`), 1000)
});
위와 같은 코드가 존재한다.
아래의 두 코드는 동일하게 동작한다.
getA()
.then(A => getB(A))
.then(B => getC(B))
.then(ABC => console.log(ABC));
getA() //
.then(getB)
.then(getC)
.then(console.log);
단 하나의 값을 전달하고 받을 때는 위 코드처럼 생략이 가능하다.
두 번째 getA()에 // 주석이 존재하지 않으면 prettier에 의해 한 줄로 바뀌게 된다.
아래는 Error 핸들링 방법이다.
// getB에서 Error가 발생되었을 때
const getB = A =>
new Promise((resolve, reject) =>
{setTimeout(() => reject(new Error(`error! ${A} => B`)), 1000)
});
getA() //
.then(getB)
.catch(error => {
return 'b';
})
.then(getC)
.then(console.log)
.catch(console.log);
위 코드처럼 then() 중간중간에 .catch()를 걸어 세밀하게 ErrorHandling이 가능하다.
Promise 사용시 주의사항
1. Promise는 선언 시에 그 값을 요청하고 받아오기 때문에 사용하지 않는 값을 가져올 수도 있다.
2. Cunsumer의 요구 사항에 따라 netNetworkConnect 가져와야 한다.
3. 누군가 요구하지 않았는데 통신이 이어지게 하면 자원이 낭비될 수 있다.
'언어 > Javascript, Typescript' 카테고리의 다른 글
[js] try...catch, finally 정리 (0) | 2023.03.23 |
---|---|
[js] async & await 정리 (0) | 2023.03.22 |
[js] 콜백함수(callback) (0) | 2023.03.21 |
[js] 코드 최적화 - falsy값, 삼항 연산자, fallback값(nullish값 체크) (0) | 2023.03.12 |
[js] 코드 최적화 - 반복문(for-of, for-in), 조건문(if문, switch문) (0) | 2023.03.07 |
댓글