배경
서버에 요청하고, 서버에 어떠한 문제가 생겨서 응답이 매우 늦게 오거나 오지 않으면 클라이언트에서 오래 기다려야 한다. 이러한 문제를 해결하기 위해서 특정 요청에 대한 응답이 일정 시간(ex: 1초) 내에 오지 않으면 서버에 문제가 있다고 간주하여 해당 작업을 종료하고 사용자가 다른 일을 할 수 있게 해야한다.
구현
Promsie.race(iterable) 를 활용하여 해당 작업을 구현할 수 있다. Promise.race(iterable) 는 인자로 받은 Promise들 중 제일 먼저 성공적으로 resolve 혹은 reject 된 Promsie를 반환한다. 즉 여기에 인자로 [request, handleTimeout] 이렇게 2개의 프로미스를 전달해서 request가 대기시간보다 늦게 resolve되면 그전에 handleTimeout을 리턴 받고 에러 처리를 할 수 있다.
const actualRunTime = 2000;
const request = (job) =>
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${job} 작업 종료`);
}, actualRunTime);
});
const timeOut = (maxWaitTime) =>
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("대기시간 초과");
}, maxWaitTime);
});
const requestWithTimeOut = async (job, maxWaitTime) => {
const result = await Promise.race([request(job), timeOut(maxWaitTime)]);
if(result === "대기시간 초과") throw Error("대기시간")
return result;
};
const reqBtn = document.querySelector("#reqBtn");
reqBtn.addEventListener("click", async () => {
console.log("요청!");
try {
const resp = await requestWithTimeOut("검사", 1000);
} catch(e) {
// 에러 핸들링
console.error(e)
}
console.log(resp);
});
요런 식으로 짜면 maxWaitTime 이 지나기전에 응답이 오면 정상적으로 함수가 진행이 되고,
maxWaitTime을 초과하면 대기시간 초과로 throw Error를 하고 콜스택서 가장 가까운 catch문으로 가서 동작을 계속한다.
이를 통해서 사용자가 서버의 이상으로 오래 기다리는 불쾌한 경험을 안하게 할 수 있다.
'프론트엔드 > JavaScript, TypeScript' 카테고리의 다른 글
타입 가드 (1) | 2023.01.25 |
---|---|
?. - Optional chaining 연산자 / ?? - Null 병합 연산자 (0) | 2022.08.22 |
디바운스와 쓰로틀 (0) | 2022.07.24 |
Vanila Js로 사진첩 사이트 만들기 (0) | 2022.03.16 |
Vanila Js로 SPA 만들기 - 리팩토링 (0) | 2022.03.15 |