💻 Dev

🛠️ 처음부터 만드는 Once — 함수를 1회만 실행하고 결과 캐싱하기

어떨 때 쓸까?


초기화 로직, 비용이 큰 계산, 이벤트 핸들러 등에서 함수를 정확히 1번만 실행하고 싶을 때입니다.
```javascript
const initApp = once(() => {
console.log('앱 초기화 (1회만!)');
return 'initialized';
});
initApp(); // "앱 초기화 (1회만!)" → 'initialized'
initApp(); // 결과 즉시 반환 (실행 안 함)
initApp(); // 결과 즉시 반환 (실행 안 함)
```

구현


```javascript
function once(fn) {
let called = false;
let result;
return function(...args) {
if (!called) {
called = true;
result = fn(...args);
}
return result;
};
}
```

실전 예제


버튼 클릭으로 API 호출 1회만 수행


```javascript
const loadData = once(async () => {
const res = await fetch('/api/init');
return res.json();
});
button.addEventListener('click', async () => {
const data = await loadData();
console.log('데이터 로드됨', data);
});
// 여러 번 클릭해도 API는 1번만 호출
```

싱글톤 패턴


```javascript
const getDB = once(() => {
console.log('DB 연결');
return { query: () => {} };
});
getDB(); // "DB 연결"
getDB(); // 캐시된 인스턴스 반환
getDB(); // 캐시된 인스턴스 반환
```

타입스크립트 버전


```typescript
function once any>(
fn: T
): (...args: Parameters) => ReturnType {
let called = false;
let result: ReturnType;
return (...args: Parameters) => {
if (!called) {
called = true;
result = fn(...args);
}
return result;
};
}
```

주의점


  • 함수 인자는 무시됨: 첫 호출 인자로만 실행됨

  • 비동기 함수도 OK: Promise도 캐싱되므로 문제없음

  • 초기화 순서 중요: 여러 모듈이 `once()`로 감싼 함수를 공유할 때는 첫 호출 순서가 중요할 수 있음

  • [MDN - Once Pattern](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)
    💬 0
    👁 0 views

    Comments (0)

    💬

    No comments yet.

    Be the first to comment!