드림코딩 엘리 JS 내용 정리(12) - Promiss

이종호·2021년 2월 22일
0

JavaScript

목록 보기
13/19
post-thumbnail

Promise

Promise는 하나의 객체이다.

여기서는 이전에 작성한 callback지옥 코드에서 Promise문법을 적용하면 어떻게 변경되는가를 중점적으로 다뤄보겠다.

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

    getRoles(user, onSuccess, onError) {
        setTimeout(() => {
            if(user === 'ellie') {
                onSuccess({name:'ellie', role: 'admin'});
            } else {
                onError(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, 
    user => {
        userStorage.getRoles(
            user, 
            (userWithRole) => {
                alert(`hello ${userWithRole.name}, you have a ${userWithRole.role} role`)
            },
            (error) => {
                console.log(error)
            }
        )
    },
    error => {
        console.log(error)
    }
)

나는 처음에 loginUser와 getRoles메소드를 Promise객체로 만들어야 한다는 생각은 했지만, id와 password를 어떻게 Promise객체에 넣을 수 있는지 고민했다.
class 안에서 해야겠다는 생각은 떠올리지 못했다.
-> 중요한 점은 class안에 해야겠다가 아니라 하나 위를 덮는 메소드를 만드는 방법같다.

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 = (id) => new Promise((resolve, reject) => {
        setTimeout(() => {
            if(id === 'ellie') {
                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')


function testJongho(id, password) {
    return new Promise((resolve, reject) => {
        if (id === 'jongho'){
            resolve(id)
        }
        else {
            reject(new Error('not jongho'))
        }
    })
}

userStorage.loginUser(id, password)
.then(userStorage.getRoles)
.then(user => alert(`hello ${user.name}, you have a ${user.role} role`))
.then(userStorage.test)
.catch(console.log)
  • 여기서 중요한 점은 id, password를 받기 위해 loginUser에 return값을 Promise객체로 만드는 일이 아닐까 싶다.
  • 만약 파라미터가 필요하지 않는 void형 메소드였다면 바로 new Promise로 만들지 않았을까?

마치 이것처럼

const promise = new Promise((resolve, reject) => {
    // doing some heavy work (network, read file)
    console.log('doing something...')
    setTimeout(() => {
        // resolve('ellie');
        reject(new Error('no network'));
    }, 2000)
});
  • 변수 promise는 Promise객체이며, 별다른 매개변수 없이 reject(혹은 resolve)를 호출하고 있다.
promise
    .then((value) => {
        console.log(value);
    })
    .catch(error => {
        console.log(error)
    })
    .finally(() => {
        console.log("finally")
    })
  • then, catch, finally를 Cunsumer라 하며, Promise객체를 실행하고 나서 결과(error가 났냐, 안났냐)를 기준으로 선택적으로 호출된다.
  • then같은 경우 error없을 때를 보통 지칭하며, 매개변수로 Promise객체를 가진다.
  • catch는 위 코드를 실행하다 error가 발생했을 때 실행되며, 에러 검출용으로 쓰인다.
  • finally같은 경우 then이나 catch나 상관없이 호출된다. JAVA에선 network관련 객체를 불러올때 close를 항상 호출하기 위해 사용했는데 여기선 어떨때 사용할지 모르겟다.
    (당연히 여기도 network관련 일을 하겠지만, express같은 라이브러리만 사용해서 finally를 사용할 일은 없었던 것 같다.)
profile
코딩은 해봐야 아는 것

1개의 댓글

comment-user-thumbnail
2021년 3월 12일

(•̀ᴗ•́)و ̑̑ 아잣

답글 달기