🛠️ 처음부터 만드는 Tap — 디버깅과 부작용을 안전하게 처리하기
# 처음부터 만드는 Tap
파이프라인 중간에서 값을 검사하거나 로그를 남기고 싶을 때가 있습니다. Tap은 부작용(side effect)을 격리하고, 값을 그대로 통과시키는 함수형 프로그래밍의 핵심 패턴입니다.
```javascript
const tap = (fn) => (value) => {
fn(value);
return value;
};
```
단 3줄입니다. 함수를 받아서, 값을 받는 함수를 반환합니다. 그 값에 대해 함수를 실행하고, 값을 그대로 반환합니다.
```javascript
const pipe = (value, ...fns) => fns.reduce((v, f) => f(v), value);
const result = pipe(
[1, 2, 3],
tap(arr => console.log('원본:', arr)),
arr => arr.map(x => x * 2),
tap(arr => console.log('2배:', arr)),
arr => arr.filter(x => x > 2),
tap(arr => console.log('필터링:', arr))
);
// 원본: [1, 2, 3]
// 2배: [2, 4, 6]
// 필터링: [4, 6]
console.log(result); // [4, 6]
```
1. 불변성 유지: 값을 변경하지 않고 검사만 합니다
2. 파이프라인 유연성: 로깅을 추가/제거해도 데이터 흐름은 변하지 않습니다
3. 테스트 용이: 부작용이 명시적이므로 목(mock)으로 검증 가능합니다
다음 시간에는 Retry — 실패한 작업을 자동으로 재시도하는 패턴을 알아봅니다.
파이프라인 중간에서 값을 검사하거나 로그를 남기고 싶을 때가 있습니다. Tap은 부작용(side effect)을 격리하고, 값을 그대로 통과시키는 함수형 프로그래밍의 핵심 패턴입니다.
구현
```javascript
const tap = (fn) => (value) => {
fn(value);
return value;
};
```
단 3줄입니다. 함수를 받아서, 값을 받는 함수를 반환합니다. 그 값에 대해 함수를 실행하고, 값을 그대로 반환합니다.
사용 예
```javascript
const pipe = (value, ...fns) => fns.reduce((v, f) => f(v), value);
const result = pipe(
[1, 2, 3],
tap(arr => console.log('원본:', arr)),
arr => arr.map(x => x * 2),
tap(arr => console.log('2배:', arr)),
arr => arr.filter(x => x > 2),
tap(arr => console.log('필터링:', arr))
);
// 원본: [1, 2, 3]
// 2배: [2, 4, 6]
// 필터링: [4, 6]
console.log(result); // [4, 6]
```
왜 필요한가?
1. 불변성 유지: 값을 변경하지 않고 검사만 합니다
2. 파이프라인 유연성: 로깅을 추가/제거해도 데이터 흐름은 변하지 않습니다
3. 테스트 용이: 부작용이 명시적이므로 목(mock)으로 검증 가능합니다
다음 시간에는 Retry — 실패한 작업을 자동으로 재시도하는 패턴을 알아봅니다.
👁 0 views
Comments (0)
💬
No comments yet.
Be the first to comment!