08
24
728x90

promise :

1) 비동기를 간편하게 처리할 수 있도록 도와주는 오브젝트

2) 정해진 장시간의 기능을 수행 후 정상적으로 수행되었다면 성공의 메시지와 함께 결과값을 전달, 기능 수행시 예상치못한 문제가 발생하면 에러를 전달

3) promise는 자바스크립트내에 내장되어있는 오브젝트

4) state : pending(만들어져서 지정된 오퍼레이션을 실행중) -> fulfilled(완료한 상태) or rejected(파일을 찾을 수 없거나 네트워크에 문제가 생기는 경우)

5) Producer(원하는 기능을 수행하여 해당하는 데이터를 만들어내는 것) vs Consumer(원하는 데이터를 소비)


<!DOCTYPE html>
<html lang = "en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" consent="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <script src="async/promise.js"></script>
    </head>
    <body></body>
</html>

1. Producer

1) promise는 클래스이기 때문에 new 키워드를 사용하여 오브젝트를 생성해줌

2) 시간이 걸리는 작업들은 promise로 만들어서 비동기적으로 처리하는것이 좋음

3) promise가 생성되는 순간 executor라는 callback함수가 바로 실행이 됨(자동적으로), 따라서 사용자가 버튼을 눌렀을 때만 네트워크 통신을 원하는 경우에는 적합하지 않음

const promise = new Promise((resolve, reject) => 
{
    //doing some heavy work (network, read files)
    console.log('doing something...');
    setTimeout(() => {
        resolve('ellie'); //호출 성공
        //reject(new Error('no network')); //호출 실패
    },2000);
});

출력 결과

2. Consumers : than, catch, finally

1) than : promise가 정상적으로 잘 수행 되어서 마지막에 최종적으로 resolve라는 callback 함수를 통해 전달된 값이 value의 파라미터로 전달됨

2) finally : 성공 실패와 관계 없이 무조건 마지막에 한번 실행

promise
    .then((value) => //성공시
    {
        console.log(value);
    })
    .catch(error => //실패시
    {
        console.log(error);
    })
    .finally(() =>
    {
        console.log('finally');
    }) //성공 실패와 관계없이 무조건 마지막에 한번실행

(성공) 출력 결과

3. Promise chaining

const fetchNumber = new Promise((resolve, reject) =>
{
    setTimeout(resolve(1), 1000); //resolve(1) : 1이 전달
})

//then은 값을 바로 전달해도 되고 promise를 전달해도됨
fetchNumber
.then(num => num *2) // 1*2 = 2
.then(num => num *3) // 2*3 = 6
.then(num => 
{
    return new Promise((resolve, reject) =>
    {
        setTimeout(() => resolve(num - 1), 1000); //6-1 = 5
    })
})
.then(num => console.log(num)); //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);
    })
const cook = egg =>
    new Promise((resolve, reject) =>{
        setTimeout(() => resolve(`${egg} => 🍳`),1000);
    })

getHen()
    .then(hen => getEgg(hen)) //.then(getEgg) 받은걸 전달하는 경우에는 이렇게 표현도 가능
    .then(egg => cook(egg))
    .then(meal => console.log(meal));

출력 결과


promise를 사용하여 고친 callback지옥 코드

<!DOCTYPE html>
<html lang = "en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" consent="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <script src="async/callback-to-promise.js"></script>
    </head>
    <body></body>
</html>
'use stict'

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); //2초후에
        })
    }
    getRoles(user)
    {
        return new Promise((resolve, reject) =>
        {
            setTimeout(() => {
                if(user === 'ellie')
                {
                    resolve({name: 'ellie', role: 'admin'});
                }
                else
                {
                    reject(new Error('no access'));
                }
            }, 1000); //1초후에
        })

    }
}

//1. 사용자에게 id와 password를 입력받음
//2. 서버에 로그인
//3. 로그인에 성공한 아이디를 받아서 다시 역할을 요청해 받아옴
//4. 사용자 오브젝트를 출력

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);

id 입력
password 입력
출력 결과

728x90
COMMENT