ES6

9. promise

으누아빠 2020. 7. 14. 15:06
반응형

promise

  • javascript에서 제공하는 비동기를 간편하게 처리하는 Object

  • 정해진 기능을 수행하고 나서 결과가 정상이라면 처리된 결과값을 반환

  • 문제발생시 에러 반환

  • state:pending 기능 수행중 -> fulfilled 수행완료 or rejected 거절

  • Producer 해당 기능을 수행하고 나서 원하는 데이터를 만드는 과정

  • Consumer 원하는 데이터를 소비하는 과정

//Immediatly resolved
const myPromise = Promise.resolve('Foo');
myPromise.then(console.log); //결과값 Foo
  • 형식 new Pomise((resolve, reject) => { })
  • resolve: 기능을 정상적으로 수행하다 마지막에 최종데이터를 전달하는 callback 함수
  • reject: 기능을 수행하다 문제가 생겼을때 호출되는 callback함수
  • state: pending(기능 수행중) -> fulfilled (수행완료) or rejected (거절)
  • Producer 해당 기능을 수행하고 나서 원하는 데이터를 만드는 과정
  • Consumer 원하는 데이터를 소비하는 과정
  1. Producer [Promise를 만드는 과정]
const promise = new Promise((resolve, reject) => {
    // doing some heavy work(network, read files)
    console.log('doing something...'); // 결과값 doing something
    setTimeout(() => {
        resolve('elle'); //elle 라는 데이터를 resolve라는 callback함수를 통해 전달
    }, 2000);
});
  • Promise 객체가 생성될때 callback 함수 부분이 즉시 실행
  • 즉 사용자의 요구에 따라 실행되어야 하는 기능인 경우 promise를 이용하면 안됨
  1. Consumers: then, catch, catch [Promise를 이용하여 만들어진 값을 받아오는 과정]
  • value: resolve callback 함수에 전달된 데이터 (위에서는 elle 라는 데이터)
//then() 을 통해 성공한 값을 가져오는 경우

promise.then((value) => {
    console.log(value); // 결과값 elle
});

// catch 통해 오류발생한 값을 가져올경우 
const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error('no network'));
    }, 2000);
});

promise.catch((error) => {
    console.log(error); // 실패한값 결과값 Error: no network
});

//finally()를 통해 성공,실패에 상관없이 무조건 실행되어야 하는 경우

promise
    .then((value) => {
        console.log(value); // 성공한값
    })
    .catch((error) => {
        console.log(error); // 실패한값
    })
    .finally(() => {
        console.log('finally'); //성공과 실패에 상관없이 무조건 실행
    });
  1. Promise chaining [then,catch등을 연속적으로 연결하여 작성하는 경우]
const fetchNumber = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(1); //1초후에 1이란 값을 전달
    }, 1000);
});

fetchNumber
    .then((num) => num * 2) //num에 1이 전달되어 1*2 = 2
    .then((num) => num * 3) //num에 2가 전달되어 2*3 = 6
    .then((num) => {
        return new Promise((resolve, reject) => {
            setTimeout(() => resolve(num - 1), 1000); //num에 6이 전달되어 6-1 5란 값이 1초 후에 실행
        });
    })
    .then((num) => console.log(num)); //결과값 2초후에 5란값이 출력
  1. Error Handling
    const getHen = () =>
     new Promise((resolve, reject) => {
         setTimeout(() => resolve('🐔'), 1000);
     });

const getEgg = (hen) =>  
new Promise((resolve, reject) => {  
setTimeout(() => reject(new Error(`${hen} => 🥚`)), 1000);  
});

const cook = (egg) =>  
new Promise((resolve, reject) => {  
setTimeout(() => resolve(`${egg} => 🍳`), 1000);  
});

// 넘겨 받은 인수 와 전달할 인수가 같은경우 생략이 가능  
getHen() //  
.then(getEgg)  
.then(cook)  
.then(console.log)  
.catch(console.log);  
// 결과값 Error: 🐔 => 🥚  
// reject가 발생한 순간 바로 catch 로 넘어가게 된다.

getHen() //  
.then(getEgg)  
.catch((error) => '🍞')  
.then(cook)  
.then(console.log)  
.catch(console.log);  
// 결과값 🍞 => 🍳  
// 각각의 then 밑에 catch를 작성하게 되면 관련된 곳에서 reject가 발생할때 마다 catch가 실행됨

예제 1

기본

const getHen = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('🐔');
        }, 1000);
    });
};

const getEgg = (hen) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(`${hen} => 🥚`);
        }, 1000);
    });
};

const cook = (egg) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(`${egg} => 🍳`);
        }, 1000);
    });
};

getHen()
    .then((hen) => getEgg(hen))
    .then((egg) => cook(egg))
    .then((meal) => console.log(meal));

최적화 1

const getHen = () =>
    new Promise((resolve, reject) => {
        setTimeout(() => resolve('🐔'), 1000);
    });

const getEgg = (hen) =>
    new Promise((resolve, reject) => {
        setTimeout(() => resolve(`${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));

최적화 2

const getHen = () =>
    new Promise((resolve, reject) => {
        setTimeout(() => resolve('🐔'), 1000);
    });

const getEgg = (hen) =>
    new Promise((resolve, reject) => {
        setTimeout(() => resolve(`${hen} => 🥚`), 1000);
    });

const cook = (egg) =>
    new Promise((resolve, reject) => {
        setTimeout(() => resolve(`${egg} => 🍳`), 1000);
    });

// 넘겨 받은 인수 와 전달할 인수가 같은경우 생략이 가능
getHen() //
    .then(getEgg)
    .then(cook)
    .then(console.log);

예제 2

class UserStorage {
    loginUser(id, password) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if ((id === 'ellie' && password === 'dream') || (id === 'coder' && password === 'academy')) {
                    resolve(id);
                } else {
                    reject(new Error('not found'));
                }
            }, 2000);
        });
    }

    getRoles(user) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if (user === 'ellie' && password === 'dream') {
                    resolve({ name: 'ellie', 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)
    .then((user) => alert(`Hello ${user.name}, you have a ${user.role} role`))
    .catch(console.log);

// 결과값 [성공] Hello ellie, you have a admin role
// 결과값 [실패] Error: not found

'ES6' 카테고리의 다른 글

11. generators 생성기  (2) 2020.07.15
10. async 와 await  (0) 2020.07.15
8. Set, Map, WeakSet, WeakMap  (0) 2020.07.09
7. New String & Number Methods  (0) 2020.07.08
6. Template Literals  (0) 2020.07.08