Promise race는 promise끼리 경주를 시킨다고 보면 될 것 같다.
같은 기능의 api를 중복 호출 하는 경우
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function searchApiv1() {
await delay(Math.random() * 5000);
return 'searchApiv1'
}
async function searchApiv2() {
await delay(Math.random() * 5000);
return 'searchApiv2'
}
const res = await Promise.race([searchApiv1(), searchApiv2()])
console.log(res)
자 위의 코드를 잠깐만 살펴보자, searchApiv1, searchApiv2은 각각 5초이내에 완료가 되는 api라고 보면 된다. 둘 중 하나의 api의 결과만 필요한 경우, 위처럼 작성하면 된다.
뭐 물론 위와 같은 코드를 짤만한 상황이 그렇게 많지는 않을 것이다. 조금 현실적인 예제를 보도록 하자.
클라이언트 에서의 api타임아웃 구현
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function searchApi() {
await delay(Math.random() * 5000);
return 'searchApiv1'
}
async function requestTimeout(ms) {
await delay(ms)
throw 'request time out'
}
try {
const res = await Promise.race([searchApi(), requestTimeout(2000)])
console.log(res);
} catch(err) {
console.error(err)
}
위와 같은 경우는 어떠한가? 특정 api의 호출이 얼마나 걸릴지 모르는 상황 혹은 응답 값이 올지 애매한 외부의 호출 같은 경우 말이다.
위의 코드에서는 searchApi함수의 호출이 2초이내로 끝나지 않으면 강제적으로 종료 하는 코드로 변경 하였다.
Promise 상태확인
promise의 상태를 확인 할 만한 상황은 그렇게 많지는 않다. 특정 사용자의 액션 중 api 중복 호출에 대해 대응 하거나, 하는 상황에서는 필요할 수 있다.
하지만 promise객체 자체에는 상태값을 표현하는 속성이 없으니 해당 필요한 경우 Promise.race를 사용이 가능하다.
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function searchApiv() {
await delay(Math.random() * 5000);
return 'searchApiv1'
}
async function requestTimeout(ms) {
await delay(ms)
throw 'request time out'
}
async function checkPromiseState(promise) {
try {
const state = await Promise.race([promise, Promise.resolve('pending')])
return state === 'pending' ? 'pending' : 'fulfilled'
} catch (e) {
return 'rejected'
}
}
const res = Promise.race([searchApiv(), requestTimeout(2000)])
await delay(2000)
console.log(await checkPromiseState(res))
위와 같이 작성하게 되면, 2초 뒤에 api호출이 완료 되었는지에 대한 여부
pending/fulfilled/rejected 상태를 확인이 가능하다.
댓글
댓글 쓰기