프로미스
: 콜백 함수의 단점을 보완하기 위해 나온 비동기 처리에 사용되는 객체
생성자 함수를 호출하여 인스턴스화할 수 있음
프로미스의 생성자 함수는 resolve와 reject함수를 인자로 전달받는 콜백함수(비동기 함수)를 인자로 전달받음.
비동기 처리 성공하여 resolve 함수를 호출하면 성공 상태(fulfilled)의 프로미스 객체가 반환되고, reject 함수가 호출 된 경우 실패 상태(rejected)의 프로미스 객체가 반환됨.
resolve함수가 실행되면 then 메소드가 자동으로 실행됨
reject함수가 실행되면 catch 메소드가 자동으로 실행됨
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
});
myPromise.then(n => {
console.log(n);
});
이전 글의 콜백지옥 예시를 프로미스를 사용하여 고쳐보자
function randomTime() {
return Math.floor(Math.random() * 10) * 1000;
}
function getChicken() {
return new Promise((resolve,reject)=>{
setTimeout(() => {
console.log('동묘시장 -> chicken');
resolve(getEgg)
}, randomTime());
})
}
function getEgg() {
return new Promise((resolve,reject)=>{
setTimeout(() => {
console.log('동묘시장 -> chicken -> egg');
resolve(getMeal)
}, randomTime());
})
}
function getMeal() {
return new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('동묘시장 -> chicken -> egg -> fried egg');
}, randomTime());
})
}
getChicken()
.then((data) => data())
.then((data) => data())
.then((data) => console.log(data));
// then method의 체이닝을 통해 비동기적으로 처리되는 코드의 실행 순서를 정할 수 있다.
Promise예제
function longWork2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("b를 만들어내는 오래걸리는 작업을 한다");
resolve(2);
}, 2000);
});
}
function longWork() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("a를 만들어내는 오래걸리는 작업을 한다");
resolve(1);
}, 1000);
});
}
let a, b;
longWork()
.then((res) => {
a = res;
return longWork2();
})
.then((res) => {
b = res;
console.log(a + b);
});
생각보다 then을 여러 개 체이닝한 예제를 만드는 것이 쉽지는 않은 것 같다. 지금의 코드에서는 then절이 두 개 뿐이지만 then절이 여러번 체이닝 되면 보기 힘든 코드가 될 것이다. 이러한 단점을 보완하기위해 async, await이 나오게 되었다.
함수를 선언할 때 함수의 앞부분에 async 키워드를 붙인다.
→ 함수에서 async
를 사용하면, 해당 함수는 결과값으로 Promise 를 반환하게 된다.
Promise 앞부분에 await
을 넣어 해당 프로미스가 끝날 때 까지 기다렸다가 다음 작업을 수행할 수 있게 한다, 그리고 프라미스 객체의 fulfilled 값을 반환
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function process() {
console.log('안녕하세요!');
await sleep(1000); // 1초쉬고
console.log('반갑습니다!');
}
process().then(() => {
console.log('작업이 끝났어요!');
});
//안녕하세요, 1초쉬고, 반갑습니다, 작업이 끝났어요!
위의 Promise예제를 async, await로 바꿔보기
function longWork2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("b를 만들어내는 오래걸리는 작업을 한다");
resolve(2);
}, 2000);
});
}
function longWork() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("a를 만들어내는 오래걸리는 작업을 한다");
resolve(1);
}, 1000);
});
(async function(){
let a = await longWork();
let b = await longWork2();
console.log(a + b);
})();