JavaScript Promise 유틸리티
비동기 프로그래밍을 위한 재시도(retry), 타임아웃(timeout), 동시성 제어(pool), 디바운스(debounce) 등 유용한 Promise 패턴 모음입니다.
/**
* 지정된 시간만큼 대기합니다.
*/
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
/**
* Promise에 타임아웃을 적용합니다.
*/
const withTimeout = (promise, ms) => {
const timeout = new Promise((_, reject) =>
setTimeout(() => reject(new Error(`Operation timed out after ${ms}ms`)), ms)
);
return Promise.race([promise, timeout]);
};
/**
* 실패 시 지정된 횟수만큼 재시도합니다.
*/
const retry = async (fn, retries = 3, interval = 1000) => {
try {
return await fn();
} catch (error) {
if (retries <= 0) throw error;
await delay(interval);
return retry(fn, retries - 1, interval);
}
};
/**
* 비동기 함수의 동시 실행 수를 제한합니다.
*/
const promisePool = async (tasks, concurrency) => {
const results = [];
const executing = new Set();
for (const task of tasks) {
const p = Promise.resolve().then(() => task());
results.push(p);
executing.add(p);
const clean = () => executing.delete(p);
p.then(clean).catch(clean);
if (executing.size >= concurrency) {
await Promise.race(executing);
}
}
return Promise.all(results);
};
/**
* 비동기 디바운스 함수입니다.
*/
const debounceAsync = (fn, ms) => {
let timeout;
return (...args) => {
clearTimeout(timeout);
return new Promise((resolve) => {
timeout = setTimeout(() => resolve(fn(...args)), ms);
});
};
};
// 사용 예시
const fetchData = () => fetch('https://api.example.com/data').then(res => res.json());
(async () => {
try {
const data = await retry(() => withTimeout(fetchData(), 5000), 3);
console.log(data);
} catch (err) {
console.error('Final error:', err.message);
}
})();