Promise는 비동기 작업의 최종 완료 또는 실패를 나타내는 객체입니다. 대부분 여러분은 이미 만들어진 promise를 사용했었기 때문에 이 가이드에서는 어떻게 promise를 만드는지 설명하기에 앞서 promise의 사용법에 대해 설명합니다.
기본적으로 promise는 함수에 콜백을 전달하는 대신에, 콜백을 첨부하는 방식의 객체입니다.
MDN에서 프로미스를 사용하는 방법에 대해서는 이런식으로 설명하고있다.
콜백은 자바스크립트 Event Loop가 현재 실행중인 콜 스택을 완료하기 이전에는 절대 호출되지 않습니다.
비동기 작업이 성공하거나 실패한 뒤에 then() 을 이용하여 추가한 콜백의 경우에도 위와 같습니다.
then()을 여러번 사용하여 여러개의 콜백을 추가 할 수 있습니다. 그리고 각각의 콜백은 주어진 순서대로 하나 하나 실행되게 됩니다.
그리고 프로미스는 위와같은 특징을 보장한다.
간단한 코드로 프로미스의 사용에 대해 보자
const promise1 = new Promise((resolve, reject) => {
resolve("Success"); //Success
});
promise1.then(
data => {
console.log(data);
}
)
resolve 함수에 파라미터로 들어간 값이 출력되는것을 알 수 있다.
setTimeout()을 사용하면 resolve가 호출되기 전 까지 일정 시간을 기다릴 수 있다.
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("Error"));
}, 2000);
});
promise1.then(
data => {
console.log(data);
}
)
.catch(
err => {
console.error(err);
}
)
reject를 이용해서 오류를 처리하는 모습이다.
프로미스가 성공할때는 .then()을 사용하고
실패해서 오류를 처리할땐 .catch()를 이용한다.
프로미스에서 반환된것을 후속 프로미스의 기반으로 사용하여 프로미스를 계속해서 연결할 수 있다.
보통 두 개 이상의 비동기 작업을 순차적으로 실행해야 하는 상황을 흔히 보게 됩니다. 순차적으로 각각의 작업이 이전 단계 비동기 작업이 성공하고 나서 그 결과값을 이용하여 다음 비동기 작업을 실행해야 하는 경우를 의미합니다. 우리는 이런 상황에서 promise chain을 이용하여 해결하기도 합니다.
const promise1 = new Promise((resolve, reject) => {
resolve();
});
promise1.then(data => {
return `working...`;
})
.then(data => {
console.log(data); //working...
throw "Failed";
})
.catch(err => {
console.error(err); //failed
});
프로미스가 성공하지않고 오류를 띄워도 연쇄적으로 연결해서 사용이 가능하다.
만약 위 코드에서는 두번째 .then()에서 오류를 띄웠지만
첫번째 .then()에서 오류를 띄우게 된다면 두번째 console.log는 실행되지 않고 바로 catch로 넘어가서 오류를 처리하게 된다.
자동으로 성공하거나 실패할때 생성한다.
둘중 하나가 나오면 바로 성공/실패 처리하기때문에 바로 연결된다.
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'first promise');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'second promise');
});
promise1.then(data => {
console.log(data);
})
promise2.then(data => {
console.log(data);
})
위코드에선 promise 1이 0.5초만에 실행되고 1초가 되었을때 promise2가 실행되는 모습을 볼수 있다.
하지만 all()을 사용하게 된다면 모든 프로미스가 성공해야 하나의 프로미스를 반환한다.
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'first promise');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'second promise');
});
Promise.all([promise1, promise2])
.then(data => {
const [promise1data, promise2data] = data;
console.log(promise1data, promise2data);
});
위의 출력결과는 1초가 지난후에 first promise second promise 가 출력된다.
만약 둘다 성공한 경우가 아니라 하나가 실패하는 경우라면
실패한 오류가 출력되면서 전체를 실패처리한다.
race()는 말그대로 가장먼저 성공 혹은 실패하는 결과를 보여준다.
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'first promise');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'second promise');
});
Promise.race([promise1, promise2])
.then(data => {
console.log(data)
});
위코드 같은경우는 promise 1이 500ms로 promise2 의 1000ms 보다 500ms나 빠르게 되니 first promise를 출력하고 종료된다.