Arrow Functuon 생략버전 확인
Promise 사용법
getHen()이 성공하면
getHen()을 통해 받아온 hen을 getEgg(hen)으로 매개변수로 넣고 실행
그 hen은 getHen에서 resolve(성공시 리턴하는 값) 🐓 임
getEgg(hen) 이행시 해당 함수가 성공시 리턴하는 값 🐓 => 🥚을 리턴하고
그 리턴된 egg를 cook(egg)로 매개변수로 넣어주고 완료시 🐓 => 🥚 => 🍳 이 리턴됨.
이리턴된 값은 meal을 매개변수로 넣고 이를 colsole.log(meal)로 출력한다.
그렇다면 최종적으로 🐓 => 🥚 => 🍳 가 출력됨
pending(대기): 비동기 처리 로직이 아직 완료되지 않은 상태
fulfilled(완료): 비동기 처리가 완료되어 프로미스 결과 값을 반환해준 상태
rejected(실패): 비동기 처리가 실패하거나 오류가 발생한 상태.
마지막 Promise Chaining에서는 아래와 같이 바꿔줄 수 있다.
getHen()
.then(hen => getEgg(hen)
.then(egg => cook(egg)
.then(finalMeal => console.log(finalMeal));
promise리턴값을 다음 promise에 그대로 대입하는 것이라면 아래 처럼 생략가능...
(이렇게 생략 가능한 문법 때문에 JS ES6 문법을 잘 모르면 더 헷갈림 ㅜㅜ)
마지막에 catch를 통해 에러를 잡아줄 수 있음
getEgg시에 문제가 생긴다면? 피자를 넣어줄게요!
문제가 생긴 것 다음에 catch를 넣으면 됨.
getHen()
.then(hen => getEgg(hen)
.catch(error => {
return '🍕';
})
.then(egg => cook(egg)
.then(finalMeal => console.log(finalMeal));
Promise를 사용하여 콜백지옥에서 벗어나는 법!
UserStorage //에서 로그인을 한다음에 (
.loginUser(id, password) // 성공하면, 유저가 전달되어 다음 then이 실행됨
.then(userStorage.getRoles)
.then(user => alert(`${user.name}, you have a ${user.role} role`);
.catch(console.log); //문제가 생기면 출력
Async
깔끔하게 promise를 사용하는 방법이 async / await임
clear style of using promise
사용법
자바스크립트는 원래 동기적으로 실행된다. 아래의 예제코드를 보자.
위에서부터 아래로 순차적으로 코드가 실행된다. 이때 네트워크 처리가 10초가 걸리면
10초 후에 console.log(user); 가 실행될 것이고, 이후에 웹페이지 화면을 처리하는 로직이 있다면
사용자는 10초 동안 빈 화면을 보게될 것이다.
이때 비동기가 필요한 것임!
function fetchUser() {
// do network request in 10 secs
// 네트워크 처리 10초
return 'dahae'
}
const user = fetchUser();
conole.log(user);
Promise를 사용하면 아래와 같이 사용됨.
비동기적으로 실행하여 끝나면 호출해줄게!
이때, 주의할 점은 resolve('dahae'); 처럼 resolve를 사용하지 않으면 PromiseState가 "fulfilled" 이 되지 않고 pending이 뜸
=> promise 안에서는 꼭 resolve나 reject로 처리를 해줘야한다!
function fetchUser() {
// do network request in 10 secs
// 네트워크 처리 10초
return new Promise((resolve, reject) => {
resolve('dahae');
});
}
const user = fetchUser();
conole.log(user);
근데, Promise를 사용하지 않고도 비동기로 사용할 수가 있다!
함수 앞에 async를 붙여주면 됨
=> 함수 안에 있는 코드블럭이 자동으로 promise로 변환됨.
async function fetchUser() {
// do network request in 10 secs
// 네트워크 처리 10초
return 'dahae';
}
const user = fetchUser();
conole.log(user);
Await
await이라는 키워드는 async라는 키워드가 붙은 함수 앞에서만 사용할 수 있다.
정해진 ms이 지나면 resolove를 리턴하는 함수
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 3초가 지나면 resolve 받아와서 사과 리턴!
async function getApple() {
await delay(3000);
return '🍎';
}
// delay가 끝날 때까지 기다려. 그리고 3초 있다가 바나나를 리턴!
async function getBanana() {
await deley(3000);
return '🍌';
}
// promise도 너무 중첩시키면 콜백지옥 같음
function pickFruites() {
return getApple().then(apple => {
return getBanana().then(banana => `${apple} + ${banana}`);
});
}
// async로 변환하기
async function pickFruits() {
const apple = await getApple();
const banana = await getBanana();
return `${apple} + ${banana}`;
}
// error 처리
async function pickFruits() {
try {
const apple = await getApple();
const banana = await getBanana();
} catch() {
}
return `${apple} + ${banana}`;
}
// 한가지 문제점
// 위의 코드에서 사과와 바나나를 받는 코드는 서로 연관이 되어있지 않다.
// 근데 사과 받는데 1초 기다려, 바나나 받는데 1초 기다려 됨. 고쳐볼까?
// 병렬적으로 사과랑 바나나랑 1초만에 가능 (서로 상관이 없기 때문임)
async function pickFruits() {
const applePromise = getApple(); //promise를 만드는 순간 프로미스 안에 있는 코드가 실행됨
const bananaPromise = getBanan(); //마찬가지로 만드는순간 코드 바로 실행됨
const apple = await applePromise();
const banana = await bananaPromise();
return `${apple} + ${banana}`;
}
// 더 간단한 api로 병렬 가능(서로 연관없는 api 호출시)
function pickAllFruites() {
return Promise.all([getApple(), getBanana()]).then(fruits => //다 받아지면 출력됨
fruits.join(' + ')
);
}
pickFruites().then(console.log);
// promise 배열 중에 가장먼저 호출된 것 전달함
function pickOnlyOne() {
return Promise.race([getApple(), getBanana()]);
}
pickOnlyOne().then(console.log); //바나나 먼저 전달됨
Promise.race()
Promise.race() 메소드는 Promise 객체를 반환합니다. 이 프로미스 객체는 iterable 안에 있는 프로미스 중에 가장 먼저 완료된 것의 결과값으로 그대로 이행하거나 거부합니다.
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
// Both resolve, but promise2 is faster
});
// expected output: "two"
=> 솔직히 실무에서 어떻게 써야할지 확 와닿지는 않는다..
Promise.all() / 자바스크립트 문법
출처: 드림코딩 앨리 promise / 캡틴판교 자바스크립트 promise 쉽게 이해하기
'[React] Front-End' 카테고리의 다른 글
[FE] React 자동완성 : clg / rafce (0) | 2021.07.15 |
---|---|
[FE] Redux (1) 개념 / 사용법 (제로초 Redux 강의 복습) (0) | 2021.07.14 |
[FE] DOM / React Hooks(UseRef()) (0) | 2021.07.06 |
[FE] ES6 map(), 그리고 reduce() (0) | 2021.07.04 |
[FE] useEffect() / 상태값을 계속 물고있으려면? (0) | 2021.06.28 |