본문 바로가기
fastcampus

[패스트캠퍼스 수강 후기] 프론트엔드 인강 100% 환급 챌린지 15회차 미션

by 새우하이 2020. 9. 21.

promise2

fulfilled 되거나 rejected 된 후에 최종적으로 실행할 것이 있다면, .filnally()를 설정하고, 함수를 인자로 넣는다.

function p(){
return  new Promise((resolve, reject) => {
    //pending
    setTimeout(() => {
        reject(new Error('bad')); //이후 fullfilled상태로 넘어감
    }, 1000);
});
}
p()
.then(message => {
//일종의 콜백을 작성하는 공간이된다.
    console.log('1000ms 후에 fulfilled 된다.', message);
})
.catch(error => {
    console.log('1000ms 후에 reject된다.', error);
})
.finally(() => {
    console.log('end')
});

실행 하면

rejected된 에러객체가 로그로 찍히고 그 후에 finally가 로그로 찍힌것을 확인할 수 있다.

promise가 없을 때 어떤식으로 작업되었는지 생각해보면 callback hell이 펼쳐졌을 수 있다 아래를 통해 확인해본다.

function c(callback){
    setTimeout(() => {
        callback();
    }, 1000);
}

이 코드가 기본적으로 비동기작업을 callback으로 처리할 때의 방식인데 다음에 진행될 함수를 callback으로 인자로 넣은 후에 작업이 끝나면 그 callback을 실행해주는 방식으로 진행되었다.

한번의 callback을 받으면

c(() => {
    console.log('1000ms 후에 callback 함수가 실행된다.');
});

두번의 콜백은

c(() => {
    c(() => {
        console.log('1000ms 후에 callback 함수가 실행된다.');
    });
});

이런식으로 계속해서 중첩되는 callback은 실행에 문제는 없지만 callback의 callback의 callback에 계속 빠지는 상황이 생길 수 있다.

promise방식으로 이를 구현하면

function p(){
    return new Promise((resolve, reject) => {
        setTimeout(()=> {
            resolve();
        }, 1000);
    });
}
p().then(() => {
    return p();
})
.then(() => p()) // {}와 return을 생략가능
.then(p)// 이자리에 p를 넣어줘도 promise객체를 또만들어서 넘겨준다.
.then(() => {
    console.log('4000ms 후에 fulfilled됨');
})

p()가 실행되고 나서 실행될 작업을 .then으로 1초후에 실행될 작업을 return p()로 실행하면 다시 새로운 promise객체를 만들어 return 한다. 이렇게 return 된 작업은 새로운 .then(() ⇒ p())로 새로 p를 부를 수있고

마지막으로 .then(p)로 promise를 만들어서 return하는 함수를 넣어주는 형태로 정의하고

마지막으로 .then으로 console.log를 출력하는 형태로 실행이 된다.


지금 까지 promise를 만들 때는 new promise를 이용하여 executor를 넣어주는 방법을 사용했는데 또 다른 방법들이 존재한다.

value가 프로미스 객체인지 아닌지 알 수 없는 경우, 사용하면 연결된 then 메서드를 실행한다.

value가 프로미스 객체면, resolve된 then 메서드를 실행하고, value가 프로미스 객체가 아니면, value를 인자로 보내면서 then 메서드를 실행한다.

Promise.resolve(/* value */);

Promise.resolve(new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve('foo');
    }, 1000);
})).then(data => {
    console.log('프로미스 객체인 경우, resolve된 결과를 받아 then이 실행된다.', 
    data,
    );
})

Promise.resolve('bar').then(data => {
    console.log('then 메서드가 없는 경우, fulfilled 된다.', data);
})

value는 프로미스 객체를 바로 넣을 수 있고 프로미스가 아닌 일반 값을 인자로 넣을 수 있다.

1초뒤에 fulfilled 되는 비동기 promise객체를 만들고 이객체를 resolve의 인자인 value에 넣어주는것이다

이후 .then이 바로 프로미스 객체가 resolve된 후에 호출된다. 이 안에 callback함수를 넣어 resolve 할 때 foo 라는 문자열을 넘겨준 값을 받아서 then이 실행 된것을 보여준다.

두번째 방법은 객체가아닌 value를 넣는데

Promise.resolve('bar')라는 문자열을 넣고 .then 의 data값이 그대로 넘어와서 fulfilled 되는것을 확인 할 수 있다.

이 예제를 실행해 보면

then 메서드가 없는 경우 1초뒤에 실행되지 않기 때문에 bar를 바로 문자열로 넘긴 결과를 출력 하고

프로미스 객체인 경우 이 프로미스 객체가 resolve 된 결과를 받아 then이 실행된다.

이는 만약 어떤 객체가 Promise객체인지 data객체인지 알 수 없을 때 promise.resolve로 실행해서 넘기면 resolve가 되게하거나 값을 바로넘기게 되게해서 유용하게 사용할 수 있다

Promise.reject를 사용하면 catch로 연결된 rejected상태로변경된다.

Promise.reject(/*value*/);
Promise.reject(new Error('reason'))
.then(error => {})
.catch(error=> {
    console.log(error);
});

이렇게 실행하면 바로 에러가 뜬다 하지만 이렇게 에러를 바로 발생시키는 경우는 많지않다.

프로미스 객체를 여러개 생성하여, 배열로 만들어 인자로 넣고 Promise.all을 실행하면, 배열의 모든 프로미스 객체들이 fulfilled 되었을 때, then의 함수가 실행된다.

then의 함수 인자로 프로미스 객체들의 resolve 된 인자 값들을 배열로 돌려준다.

function p(ms){
    return new Promise((resolve, reject)=>{
        setTimeout(() => {
            resolve();
        }, ms);
    })
}
Promise.all([p(1000), p(2000), p(3000)]).then(() => {
    console.log('모두 fulfilled 된 이후에 실행됩니다.');
})

실행하면 1초 2초 3초후 각각 모두 fulfilled 된상태가 된후에 then이 실행된다.

function p(ms){
    return new Promise((resolve, reject)=>{
        setTimeout(() => {
            resolve(ms);
        }, ms);
    })
}
Promise.all([p(1000), p(2000), p(3000)]).then((msg) => {
    console.log('모두 fulfilled 된 이후에 실행됩니다.',msg);
})

이번엔 resolve에 인자를 담아 보내고 출력해보면 Promise.all에 연결되어있는 then내부의 callback함수가 실행되고 인자로 각각의 ms가 배열로 만들어져 넘어오게되어 출력된다.

마지막으로

Promise.race 는 프로미스 객체 모두가 fulfilled 되고 then이 되는것이아니라 그중에서 가장 빠르게 fulfilled 된것이 있으면 바로 then함수가 실행된다.

function p(ms){
    return new Promise((resolve, reject)=>{
        setTimeout(() => {
            resolve(ms);
        }, ms);
    })
}
Promise.race([p(1000), p(2000), p(3000)]).then((msg) => {
    console.log('가장 빠른 객체가 fulfilled 된 이후에 실행됩니다.',msg);
})

callback의 인자로 가장 빠르게 fulfiiled된 객체의 resolve에 들어오는 값을 전달 받으므로 아마 1000이 출력될것이다.

 

해당 내용은 아래 링크에서 수강할 수 있다.

프론트엔드 개발 올인원 패키지 with React Online. 👉https://bit.ly/2ETLEzm

 

프론트엔드 개발 올인원 패키지 with React Online. | 패스트캠퍼스

성인 교육 서비스 기업, 패스트캠퍼스는 개인과 조직의 실질적인 '업(業)'의 성장을 돕고자 모든 종류의 교육 콘텐츠 서비스를 제공하는 대한민국 No. 1 교육 서비스 회사입니다.

www.fastcampus.co.kr



댓글