스터디/개인스터디(유투브 드림코딩 by엘리)(주5회)

[09] JavaScript Promise & callback to promise

d0201d 2020. 9. 11. 00:47
'use strict';

//Promise (비동기 코드를 콜백함수 대신 깔끔하게 정리하는 할수있음)
//JavaScript 안에 내장되어 있는 Obj
//State(상태) : Pending(진행중일때)  -> FullFilled or Rejected (성공적으로 마친상태이거나 || 실패하거나 파일을 찾을수 없을때)
//Producer vs Consumer


//1. Producer
//  ((중요))새로운 Promise가 만들어질 때는 여기서 전달한 executor가 자동적으로 바로 실행!!!
const promise = new Promise((resolve, reject) => {
    //doing some heavy work (files, network)
    console.log('doing something...');
    setTimeout(() => {
        // resolve('bom');
        reject(new Error('no network')); //이 행의 Error는 javascript에서 제공하는 Obj중의 하나(무언가 에러가 발생했다는 것을 나타낼때)
    }, 2000);
});

//2. Consumers: then, catch, finally
promise
//then : 성공적인 케이스일때만
    .then((value) => { //값이 정상적으로 잘 수행이 된다면 value값을 받아올것 (여기서 value는 위의 promise에서 수행이 정상적으로 이루어져서 resolve 콜백함수에서 전달된 'bom'을 말한다 )
        console.log(value); //bom
    })
    //catch : 실패인 케이스
    .catch(error => {
        console.log(error); //Error: no network
    })
    //finally : 성공과 실패 상관없이 어떤기능을 마지막으로 수행하고 싶을때 !!
    .finally(() => {
        console.log('finally'); // (bom || Error: no network) && finally
    });

//3. Promise chaining
const fetchNumber = new Promise((resolve, reject) => {
    setTimeout(() => resolve(1), 1000); //1
})
fetchNumber
    .then(num => num * 2) //2
    .then(num => num * 3) //6
    .then(num => {
        return new Promise((resolve, reject) => {
            setTimeout(() => resolve(num - 1), 1000); //5
        });
    })
    .then(num => console.log(num)); //5

//4. 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))
    .catch(error => { // 전달 받아오는 중에 오류가 있을 때 다른 것으로 대체하여 에러를 보완하는 방법
        return '빵'
    })
    .then(egg => cook(egg))
    .then(meal => console.log(meal)) //닭! => 달걀 => 후라이
    .catch(console.log); //Error: error! 닭 => 달걀

//↑↑더 간단하게 작성 가능(한가지만 받아서 그대로 전달할 경우에만!)
//getHen()
//.then(getEgg)
//.then(cook)
//.then.(console.log);

 

Promise를 사용하여 지난 콜백 예제를 깨끗하게 정리

'use strict';

//콜백지옥 예제
class UserStorage {
    loginUser(id, password) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if (
                    (id === 'bom' && password === 'dream') || // && - and , || - or
                    (id === 'coder' && password === 'academy')
                ) {
                    resolve(id);
                } else {
                    reject(new Error('not found'));
                }
            }, 2000);
        });

    }
    getRoles(user) {
        return new Promiseㅠㅐㅡ((resolve, reject) => {
            setTimeout(() => {
                if (user === 'bom') {
                    resolve({ name: 'bom', role: 'admin' });
                } else {
                    reject(new Error('no access'));
                }
            }, 1000);
        });
    }
}

const userStorage = new UserStorage();
const id = prompt('enter your id');
const password = prompt('enter your password');
userStorage
    .loginUser(id, password) // 로그인을 한 후
    .then(userStorage.getRoles) //그 유저를 이용해 getRols를 호출하게 되고
    .then(user => alert(`Hello! ${user.name}, you have a ${user.role} role`)) //성공적으로 다 수행이 된다면 최종적으로 받아오는 유저를 활용해 작성가능
    .catch(console.log); //그러다 만약 문제가 생긴다면 콘솔에 표시되게 처리