1. Promise
- callback을 대체하여 비동기를 간편하게 처리할 수 있도록 도와주는 js 안에 내장되어 있는 object
 
- 정상적으로 기능이 수행되면 성공 메세지와 결과값을 전달하고 아니면 에러를 전달한다.
 
- 1) state : process가 기능 수행을 중인지(pending), 기능수행을 완료했는지(fulfilled or rejected)의 상태를 아는 것이 중요하다.
 
- 2) data를 제공하는 사람(producer)과 제공받는/소비하는 사람(consumer)의 차이점을 정확히 알아야 한다.
 
2. Producer
const promise = new Promise((resolve, reject) => {
    console.log('doing something...');
    setTimeout(() => {
        
        
        reject(new Error('no network')); 
    }, 2000)
})
- date를 받아오는 동안(code의 'doing someting 부분) 그 다음 코드가 진행되지 않기 때문에 promise를 사용하여 비동기적으로 처리한다.
 
- 'doing something...'이 바로 출력되는 것을 보아 promise를 생성하는 순간 바로 executor 함수가 바로 실행 된 것을 확인할 수 있다(네트워크 통신 실행).
 
- 사용자가 어떤 동작을 했을 때 네트워크 요청을 해야하는 거라면 위 사실을 유의하여 코드를 짠다.
 
3. Consumer
- then, catch, finally를 이용해서 값을 받아온다.
 
promise
.then((value) => {
    console.log(value);
}) 
.catch(error => {
    console.log(error);
})
.finally(() => {console.log('finally')}); 
4. Promise chaining
- then을 묶어서 비동기 처리
 
- then은 값을 바로 전달할 수도 있고 리턴으로 promise를 전달해도 된다.
 
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)); 
5. Error handling
const getHen = () =>
    new Promise((resolve, reject) => {
        setTimeout(() => resolve('🐓'), 1000);
    }); 
const getEgg = hen =>
    new Promise((resolve, reject) => {
        setTimeout(() => resolve(`${hen} => 🥚`), 1000);
        setTimeout(() => reject(new Error(`error! ${hen} => 🥚`)), 1000);
    }); 
const cook = egg => 
    new Promise((resolve, reject) => {
        setTimeout(() => resolve(`${egg} => 🍳`), 1000);
    }); 
getHen() 
.then(hen => getEgg(hen)) 
.then(egg => cook(egg)) 
.then(meal => console.log(meal)); 
getHen()
.then(getEgg)
.catch(error => {
    return '🍟';
}) 
.then(cook) 
.then(console.log);