实战与最佳实践
实战案例
案例 1:数据验证管道
构建一个灵活的验证器:
typescript
type ValidationResult<T> =
| { success: true; data: T }
| { success: false; errors: string[] }
// 验证器工厂
const createValidator = <T>() => {
const pipeline = createPipeline<any, ValidationResult<T>>()
const rules: Array<{
name: string
check: (data: any) => boolean
message: string
}> = []
return {
// 添加验证规则
rule(name: string, check: (data: any) => boolean, message: string) {
rules.push({ name, check, message })
pipeline.use((data, next) => {
const rule = rules[rules.length - 1]
if (!rule.check(data)) {
return {
success: false,
errors: [`${rule.name}: ${rule.message}`]
}
}
return next(data)
})
return this
},
// 执行验证
validate(data: any): ValidationResult<T> {
return pipeline.run(data, {
onLast: (data) => ({ success: true, data })
})
}
}
}
// 使用
const userValidator = createValidator<User>()
.rule('email',
(d) => /@/.test(d.email),
'邮箱格式不正确'
)
.rule('age',
(d) => d.age >= 18,
'必须年满 18 岁'
)
.rule('password',
(d) => d.password.length >= 8,
'密码至少 8 位'
)
const result = userValidator.validate({
email: 'test@example.com',
age: 25,
password: 'secure123'
})
if (result.success) {
console.log('✅ 验证通过', result.data)
} else {
console.log('❌ 验证失败', result.errors)
}案例 2:状态机
用 Pipeline 实现一个简单的状态机:
typescript
import { createPipeline, createContext } from 'farrow-pipeline'
type State = 'idle' | 'loading' | 'success' | 'error'
type Event =
| { type: 'FETCH' }
| { type: 'SUCCESS'; data: any }
| { type: 'FAIL'; error: string }
| { type: 'RESET' }
const StateContext = createContext<State>('idle')
const stateMachine = createPipeline<Event, State>()
stateMachine.use((event, next) => {
const currentState = StateContext.get()
// 状态转换逻辑
switch (event.type) {
case 'FETCH':
if (currentState === 'idle') {
StateContext.set('loading')
}
break
case 'SUCCESS':
if (currentState === 'loading') {
StateContext.set('success')
}
break
case 'FAIL':
if (currentState === 'loading') {
StateContext.set('error')
}
break
case 'RESET':
StateContext.set('idle')
break
}
return next(event)
})
stateMachine.use(() => {
return StateContext.get()
})
// 使用
console.log(stateMachine.run({ type: 'FETCH' })) // 'loading'
console.log(stateMachine.run({ type: 'SUCCESS', data: {} })) // 'success'
console.log(stateMachine.run({ type: 'RESET' })) // 'idle'案例 3:请求处理管道
typescript
interface Request {
method: string
url: string
headers: Record<string, string>
body?: any
}
interface Response {
status: number
headers: Record<string, string>
body: any
}
const app = createAsyncPipeline<Request, Response>()
// 日志中间件
app.use((req, next) => {
const start = Date.now()
console.log(`→ ${req.method} ${req.url}`)
const res = next(req)
const duration = Date.now() - start
console.log(`← ${res.status} (${duration}ms)`)
return res
})
// CORS 中间件
app.use((req, next) => {
const res = next(req)
return {
...res,
headers: {
...res.headers,
'Access-Control-Allow-Origin': '*'
}
}
})
// 认证中间件
app.use((req, next) => {
const token = req.headers.authorization
if (!token) {
return {
status: 401,
headers: {},
body: { error: 'Unauthorized' }
}
}
return next(req)
})
// 路由处理
app.use((req) => {
if (req.url === '/users') {
return {
status: 200,
headers: { 'Content-Type': 'application/json' },
body: { users: [] }
}
}
return {
status: 404,
headers: {},
body: { error: 'Not Found' }
}
})最佳实践
✅ 1. 类型优先
typescript
// ✅ 好:明确指定类型
const pipeline = createPipeline<Request, Response>()
// ❌ 不好:类型推导可能不准确
const pipeline = createPipeline()✅ 2. 单一职责
每个中间件只做一件事:
typescript
// ✅ 好:职责清晰
pipeline
.use(authMiddleware)
.use(validationMiddleware)
.use(businessLogicMiddleware)
// ❌ 不好:职责混乱
pipeline.use((req, next) => {
// 认证 + 验证 + 业务逻辑全部混在一起
const user = authenticate(req)
const valid = validate(req)
const result = processRequest(req, user)
return result
})✅ 3. 合理使用 Context
适合用 Context:
- 🟢 跨中间件共享的请求级数据(用户、请求 ID)
- 🟢 需要隔离的状态
不适合用 Context:
- 🔴 全局配置(用模块变量)
- 🔴 可以通过参数传递的数据
typescript
// ✅ 好:适合用 Context
const UserContext = createContext<User | null>(null)
const RequestIdContext = createContext<string>('')
// ❌ 不必要:用模块变量就行
const ConfigContext = createContext({ apiUrl: 'https://api.example.com' })
// 改成这样:
const API_URL = 'https://api.example.com'✅ 4. 错误处理
在适当的层级处理错误:
typescript
// 全局错误处理中间件(放在最前面)
pipeline.use(async (input, next) => {
try {
return await next(input)
} catch (error) {
console.error('💥 出错了:', error)
return { status: 500, error: error.message }
}
})
// 业务逻辑可以放心抛错
pipeline.use(async (input, next) => {
const data = await riskyOperation(input) // 可能抛错
return next(data)
})✅ 5. 懒加载优化性能
typescript
// ✅ 好:懒加载重型依赖
pipeline.useLazy(async () => {
const { heavyLib } = await import('./heavy-lib')
return (req, next) => {
if (needsProcessing(req)) {
return next(heavyLib.process(req))
}
return next(req)
}
})
// ❌ 不好:启动时加载
import { heavyLib } from './heavy-lib' // 拖慢启动速度✅ 6. 测试友好
使用 Container 注入依赖:
typescript
import { createContainer } from 'farrow-pipeline'
const DatabaseContext = createContext<Database>(realDatabase)
// 测试时注入 mock
const testContainer = createContainer({
db: DatabaseContext.create(mockDatabase)
})
const result = pipeline.run(testInput, { container: testContainer })✅ 7. 可复用的中间件工厂
typescript
// 中间件工厂
const createLoggerMiddleware = (options: { level: 'info' | 'debug' }) => {
return (input: any, next: any) => {
if (options.level === 'debug') {
console.log('📝 输入:', input)
}
const result = next(input)
console.log('📝 输出:', result)
return result
}
}
// 使用
pipeline.use(createLoggerMiddleware({ level: 'debug' }))⚠️ 8. 浏览器环境不支持
typescript
// ❌ 浏览器中无法使用
import { createPipeline } from 'farrow-pipeline' // 会报错
// ✅ 仅在 Node.js 中使用常见陷阱
陷阱 1: 忘记调用 next
typescript
// ❌ 错误:忘记调用 next
pipeline.use((input, next) => {
console.log('处理中...')
// 忘记返回 next(input)
})
// ✅ 正确
pipeline.use((input, next) => {
console.log('处理中...')
return next(input)
})陷阱 2: 异步中忘记 await
typescript
// ❌ 错误:忘记 await
pipeline.use(async (input, next) => {
const result = next(input) // 返回 Promise,但没有 await
console.log(result) // Promise 对象
return result
})
// ✅ 正确
pipeline.use(async (input, next) => {
const result = await next(input)
console.log(result) // 实际值
return result
})陷阱 3: Context 在异步中丢失
typescript
// ❌ 错误:没有启用 AsyncLocalStorage
UserContext.set(user)
await delay(1000)
const u = UserContext.get() // undefined
// ✅ 正确:启用异步追踪
import * as asyncTracerImpl from 'farrow-pipeline/asyncTracerImpl.node'
asyncTracerImpl.enable()下一步
恭喜你!🎉 现在你已经掌握了 farrow-pipeline 的所有核心知识。
推荐学习路径:
- 📖 查看 完整 API 参考 - 深入了解每个 API
- 🌐 学习 farrow-http - 构建 HTTP 服务器
- 🎯 探索 farrow-schema - 类型验证
实践建议:
- 🔨 在小项目中试用 Pipeline
- 📦 封装你的常用中间件
- 🧪 为中间件编写单元测试
记住:好的代码就像好的管道,清晰、流畅、不漏水!🚰
