개발/JavaScript
2023.04.12 JavaScript의 프로미스,옵셔널체이닝
상달군
2023. 4. 12. 15:03
728x90
목차
1. JavaScript의 프로미스(Promise)
- 프로미스를 사용시 장점
- 사용법
- 프로미스를 리턴받는 객체
2. JavaScript의 옵셔널 체이닝(Optional Chaining) 연산자
1. JavaScript의 프로미스(Promise)
- 자바스크립트 비동기 처리에 사용되는 객체
(- 비동기란? -> 시간이 걸리는 처리를 잠깐 멈춰두고 다하고 다시 시작) - 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용
1-1. 프로미스를 사용시 장점
- 비동기 처리 시점을 명확하게 표현할 수 있다.
- 연속된 비동기 처리 작업을 수정, 삭제, 추가하기 편하고 유연하게 만들수 있다.
- 코드의 유지 보수성이 증가한다.
1-2. 프로미스 사용법
성공 실패
---------- -------
const 프로미스객체 = () => new Promise((resolve, reject) => {
});
✔비동기 처리가 성공 또는 실패 등의 상태 정보를 갖게 되는데
resolve가 호출된 경우: 성공 (뭔가 처리가 잘 처리 된것)
reject가 호출된 경우: 실패
1-3. 프로미스를 리턴받은 객체
.then(정상적으로 프로미스 객체가 리턴되었다면 필요한 일을 수행 하는메소드)
.catch(에러 객체가 리턴되었다면 에러를 처리)
.finally(최종적으로 처리할 일을 수행)
프로미스 예시 1)
<h2>프로미스1</h2>
<script>
function runInDelay(seconds){
return new Promise((resolve, reject)=> {
if(!seconds || seconds < 0){
reject(new Error('seconds가 0보다 작다!'));
}
setTimeout(resolve, seconds * 1000);// 밀리초기때문에 1000을 곱해주면 초단위가 된다.
});
}
//메소드 체이닝(프로미스는 이러한 형태로 체이닝을 이용하여 많이들 쓴다.)
// 매개변수인 3초를 준 소스
// runInDelay(3)
// .then(()=>console.log('타이머가 완료 되었습니다.'))
// .catch(console.error)
// .finally(() => console.log('모든 작업이 끝났습니다.'));
// (실패해보기) 매개변수seconds를 넣지 않으면 값이 없기때문에 함수의 if문 안으로 걸러지게 된다.
// 매개변수인 초를 주지 않았을때 소스 (에러가 발생한다)
runInDelay()
.then(()=>console.log('타이머가 완료 되었습니다.'))
.catch(console.error)
.finally(() => console.log('모든 작업이 끝났습니다.'));
</script>
주석 처리 되어있는 소스에서 매개변수로 전달한 3초 후에 성공한 내용이 결과값으로 보인다.
실패한 소스를 실행시켰을시에는 아래와같이 에러가 전달되게된다.
프로미스2 예시)
<script>
function fetchEgg(chicken) {
return Promise.resolve(`${chicken} => 🥚`);
}
function fryEgg(egg){
return Promise.resolve(`${egg} => 🍳`);
}
function getChicken(){
return Promise.resolve(`🐤 => 🐓`);
//return Promise.reject(new Error('치킨집 망함.'));
}
getChicken()
.then((chicken) => {
return fetchEgg(chicken);
})
.then((egg) => fryEgg(egg))
.then((friedEgg)=> console.log(friedEgg))
.catch(()=> '🐥'); // catch는 위치가 중요하다. 에러가 발생했을때 멈추는게아니고 밑에 then이 있다고 하면 then에 값을 가지고 간다.
// 위 코드 축약형
// getChicken()
// .then(fetchEgg)
// .then(fryEgg)
// .then(console.log)
// .catch(()=> '🐥');
</script>
프로미스3 예시)
<script>
function getBanana(){
return new Promise((resolve)=>{
setTimeout(()=>{
resolve('🍌');
}, 1000);
});
}
function getApple(){
return new Promise((resolve)=>{
setTimeout(()=>{
resolve('🍎');
}, 3000);
});
}
function getOrange(){
return Promise.reject(new Error('오렌지는 다 팔림!!'));
}
// 후 처리 메소드 사용
// 바나나와 사과 동시에 가져오기
// 순차적으로 처리 -> 총 4초가 걸림
// 바나나와 사과를 배열에 저장해서 콘솔에 출력
getBanana()
.then((banana)=>
getApple()
.then((apple) => [banana, apple]))
.then(console.log);
// Promise.all (병렬적으로 실행하는것)
// 병렬적으로 한번에 모든 Promise들을 실행
Promise.all([getBanana(), getApple()])
.then((fruits)=>console.log('Promise.all:', fruits));
// all의 특징: 하나라도 실패하면 전체가 실패 한다.
Promise.all([getBanana(), getApple(), getOrange()])
.then((fruits)=> console.log('Error:', fruits))
.catch(console.log);
// Promise.allSettled
// 에러가 발생하더라도 모든 프로미스들의 결과를 반환 받을수 있다.
Promise.allSettled([getBanana(), getApple(), getOrange()])
.then((fruits)=>console.log('Promise.allSettled:', fruits))
.catch(console.log);
// Promise.race
// 주어진 프로미스 중에서 가장 빨리 수행된 것을 출력해주는 메소드
Promise.race([getBanana(), getApple()])
.then((fruit)=>console.log('Promise.race:', fruit));
2. JavaScript의 옵셔널 체이닝(Optional Chaining) 연산자
- 우리가 배우는 문법중 제일 최근에 추가된 애
- ECMA Script 11버전에 추가 된 내용
- null 또는 undefined를 확인할 때 쓰이는 연산자
- ?. , ??
예시 )
let dog = {} //값이 비어있는 dog
dog && dog.name && dog.age // 값이 비어있는걸 확인 하는 방법
dog?.dog.name //dog이 있니?.dog의 name
dog.name?.age
<script>
// 논리 연산자 (&&, ||)
const obj1 = {name:'김사과'};
const obj2 = {name:'반하나', lover:'이메론'};
const bool1 = false;
if(obj1 || obj2){// obj1,obj2둘다 값이 존재 하기때문에 true
console.log('둘중 하나는 true');
}
let result = obj1 && obj2;// obj1가 참이고 넘어가서 obj2를 확인해서 obj2가 참이면 obj2를 result로 값을 저장한다. obj1이 거짓이면 뒤로 obj2는 확인조차 하지 않고 obj1을 저장하게 된다.
console.log(result);
result = obj1 || obj2;// obj1이 참이면 둘중 하나만 참이면 되니깐 굳이 obj2까지 갈필요가 없어서 obj1이 result에 저장된다.
console.log(result);
function changeLover(obj){
if(!obj.lover){
throw new Error('애인이 없어!');
}
obj.lover = '애인이 바뀜';
}
function makeNewLover(obj){
if(obj.lover){
throw new Error('애인이 있어!');
}
obj.lover = '새로운 애인이 생김';
}
console.log('-----------');
obj1.lover && changeLover(obj1);// obj1에는 lover이 존재 하지 않기 때문에 changeLover함수가 실행 조차 되지 않는다. 그래서 obj1의 값이 그냥 출력 된다.
console.log(obj1);
console.log('-----------');
obj2.lover && changeLover(obj2);
console.log(obj2);
console.log('-----------');
// null 또는 undefined인 경우를 확인할 때
let item = {price:1000};
const price = item && item.price;// item객체가 존재 하는지 확인하고 item의 price객체를 price객체에 저장
console.log(price);
console.log('-----------');
// 기본값을 설정
// 자바스크립트의 default parameter: undefined이다.
function print(message){
const text = message || 'hello';
//print('안녕'): message에 "안녕"이 존재 하기 때문에 hello로 가지 않는다.
//print(): message에 존재 하지 않기 때문에 hello로 출력
console.log(text);
}
print('안녕'); // 안녕
print(); // hello
print(undefined); // hello
print(null); // hello
print(''); // hello
console.log('-----------');
let item2 = {price: 1000};
const price2 = item2?.price; //=> 'item && item.price'랑 같은 이야기
console.log(price2);
console.log('-----------');
let banana = {name:'반하나', lover:{name:'오렌지'}};
function printLoverName(obj){
const loverName = obj?.lover?.name;
console.log(loverName);
}
printLoverName(banana);
console.log('-----------');
//let num = null;
let num = 0;
console.log(num || '-1'); // num은 0이기 때문에 false 그래서 '-1'이 출력된다.
console.log(num ?? '-1');//null, undefined 이라면 대체값을 출력
// ?? = 대체값 (=앞이 false라면 뒷에 값으로 대체 해줘라)
console.log(banana.lover?.name??'이메론');
</script>
728x90