💻 Dev

🛠️ 처음부터 만드는 Once — 함수를 한 번만 실행하기

문제


어떤 함수는 반복 호출되어도 정확히 한 번만 실행되어야 합니다. 초기화, 싱글톤 패턴, 이벤트 리스너 등에서 필수입니다.
```javascript
const initialize = () => console.log('초기화 중...');
initialize(); // 초기화 중...
initialize(); // 초기화 중... ← 다시 실행됨 (문제!)
initialize(); // 초기화 중...
```

해결책


`Once`는 클로저를 활용해 첫 호출 결과를 기억합니다.
```javascript
function once(fn) {
let result;
let called = false;
return function (...args) {
if (!called) {
result = fn.apply(this, args);
called = true;
}
return result;
};
}
```

사용 예


```javascript
const initialize = once(() => {
console.log('초기화 중...');
return 'ready';
});
initialize(); // 초기화 중... → 'ready'
initialize(); // (아무 출력 없음) → 'ready'
initialize(); // (아무 출력 없음) → 'ready'
```

실무 활용


데이터베이스 연결:
```javascript
const connectDB = once(async () => {
return await dbClient.connect();
});
await connectDB(); // 첫 호출: 실제 연결
await connectDB(); // 이후: 캐시된 연결 반환
```
이벤트 리스너 한 번만 등록:
```javascript
const setupListener = once(() => {
window.addEventListener('resize', handleResize);
});
setupListener(); // 등록됨
setupListener(); // (중복 등록 없음)
```

핵심 개념


  • 클로저: `called`, `result` 변수가 메모리에 유지됨

  • Side Effect 제어: 첫 호출만 실행, 이후는 결과 재사용

  • 디버깅: called 플래그로 실행 여부 추적 가능

  • 심화: 재설정 기능


    ```javascript
    function once(fn) {
    let result, called = false;
    const wrapper = function (...args) {
    if (!called) {
    result = fn.apply(this, args);
    called = true;
    }
    return result;
    };
    wrapper.reset = () => { called = false; };
    return wrapper;
    }
    const init = once(() => console.log('init'));
    init(); // init
    init.reset();
    init(); // init (재실행됨)
    ```
    💬 0
    👁 0 views

    Comments (0)

    💬

    No comments yet.

    Be the first to comment!