🛠️ 처음부터 만드는 Once — 함수를 단 한 번만 실행하기
문제 상황
버튼을 여러 번 클릭하면 함수가 여러 번 실행되는 경우가 있습니다. 폼 제출, API 호출 같은 작업에서는 정확히 한 번만 실행해야 합니다.
```javascript
// ❌ 문제: 사용자가 버튼을 빠르게 여러 번 클릭하면 중복 실행
const handleSubmit = async () => {
await api.post('/data', { name: 'test' });
};
button.addEventListener('click', handleSubmit); // 버튼 3번 클릭 = 3번 실행됨
```
Once 만들기
`Once`는 함수를 래핑해서 아무리 많이 호출해도 정확히 한 번만 실행하게 만듭니다.
```javascript
function once(fn) {
let called = false;
let result;
return function(...args) {
if (!called) {
called = true;
result = fn.apply(this, args);
}
return result;
};
}
// 사용 예제
const processData = once(() => {
console.log('데이터 처리 중...');
return 'processed';
});
processData(); // "데이터 처리 중..." 출력
processData(); // 무시됨
processData(); // 무시됨
```
실제 사용 예제
```javascript
// 1. 폼 제출 방지
const submitForm = once(async (data) => {
await fetch('/api/submit', { method: 'POST', body: JSON.stringify(data) });
});
form.addEventListener('submit', (e) => {
e.preventDefault();
submitForm({ name: 'John' });
});
// 2. 초기화 작업 (한 번만 실행)
const initDb = once(() => {
console.log('데이터베이스 연결 중...');
return new Database();
});
initDb(); // 첫 번째만 실행
initDb(); // 무시됨
```
TypeScript 버전
```typescript
function once
let called = false;
let result: any;
return ((...args: any[]) => {
if (!called) {
called = true;
result = fn(...args);
}
return result;
}) as T;
}
```
Before/After
```javascript
// ❌ Before: 3번 클릭 = 3번 API 호출
const handleBuy = async () => {
await fetch('/api/buy', { method: 'POST' });
};
buyButton.addEventListener('click', handleBuy); // 중복 결제 위험!
// ✅ After: 아무리 클릭해도 1번만
const handleBuy = once(async () => {
await fetch('/api/buy', { method: 'POST' });
});
buyButton.addEventListener('click', handleBuy); // 안전 ✨
```
더 배우기: [Lodash once](https://lodash.com/docs/#once), [MDN: 함수 객체](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)
👁 0 views
Comments (0)
💬
No comments yet.
Be the first to comment!