chain
將多個函數鏈接在一起,按順序執行。
語法
typescript
chain<T>(
...functions: ((value: T) => T)[]
): (value: T) => T
參數
...functions
(((value: T) => T)[]): 要鏈接的函數數組
返回值
(value: T) => T
: 鏈接後的函數
示例
基本用法
typescript
import { chain } from 'radash'
const addOne = (x: number) => x + 1
const multiplyByTwo = (x: number) => x * 2
const square = (x: number) => x * x
const pipeline = chain(addOne, multiplyByTwo, square)
const result = pipeline(3)
// 步驟: 3 -> 4 -> 8 -> 64
// 結果: 64
字符串處理
typescript
import { chain } from 'radash'
const toUpperCase = (str: string) => str.toUpperCase()
const addExclamation = (str: string) => str + '!'
const repeat = (str: string) => str + str
const processString = chain(toUpperCase, addExclamation, repeat)
const result = processString('hello')
// 步驟: 'hello' -> 'HELLO' -> 'HELLO!' -> 'HELLO!HELLO!'
// 結果: 'HELLO!HELLO!'
數組處理
typescript
import { chain } from 'radash'
const filterEven = (arr: number[]) => arr.filter(x => x % 2 === 0)
const double = (arr: number[]) => arr.map(x => x * 2)
const sum = (arr: number[]) => arr.reduce((a, b) => a + b, 0)
const processArray = chain(filterEven, double, sum)
const result = processArray([1, 2, 3, 4, 5, 6])
// 步驟: [1,2,3,4,5,6] -> [2,4,6] -> [4,8,12] -> 24
// 結果: 24
對象處理
typescript
import { chain } from 'radash'
const addId = (obj: any) => ({ ...obj, id: Date.now() })
const addTimestamp = (obj: any) => ({ ...obj, timestamp: new Date().toISOString() })
const addStatus = (obj: any) => ({ ...obj, status: 'active' })
const processObject = chain(addId, addTimestamp, addStatus)
const result = processObject({ name: 'Alice', age: 25 })
// 結果: { name: 'Alice', age: 25, id: 1234567890, timestamp: '2023-01-01T00:00:00.000Z', status: 'active' }
類型轉換
typescript
import { chain } from 'radash'
const toString = (num: number) => num.toString()
const addPrefix = (str: string) => 'Number: ' + str
const toUpperCase = (str: string) => str.toUpperCase()
const processNumber = chain(toString, addPrefix, toUpperCase)
const result = processNumber(42)
// 步驟: 42 -> '42' -> 'Number: 42' -> 'NUMBER: 42'
// 結果: 'NUMBER: 42'
條件處理
typescript
import { chain } from 'radash'
const validateAge = (age: number) => {
if (age < 0 || age > 120) {
throw new Error('Invalid age')
}
return age
}
const categorizeAge = (age: number) => {
if (age < 18) return 'minor'
if (age < 65) return 'adult'
return 'senior'
}
const addCategory = (category: string) => ({ category })
const processAge = chain(validateAge, categorizeAge, addCategory)
const result = processAge(25)
// 結果: { category: 'adult' }
錯誤處理
typescript
import { chain } from 'radash'
const safeDivide = (x: number) => {
if (x === 0) throw new Error('Division by zero')
return 100 / x
}
const addOne = (x: number) => x + 1
const multiplyByTwo = (x: number) => x * 2
const processNumber = chain(safeDivide, addOne, multiplyByTwo)
try {
const result = processNumber(5)
console.log(result) // 42
} catch (error) {
console.error('Error:', error.message)
}
try {
processNumber(0) // 拋出錯誤
} catch (error) {
console.error('Error:', error.message) // 'Division by zero'
}
異步函數鏈
typescript
import { chain } from 'radash'
const fetchUser = async (id: number) => {
const response = await fetch(`/api/users/${id}`)
return response.json()
}
const addTimestamp = (user: any) => ({
...user,
fetchedAt: new Date().toISOString()
})
const addStatus = (user: any) => ({
...user,
status: user.active ? 'active' : 'inactive'
})
// 注意:異步函數需要特殊處理
const processUser = async (id: number) => {
const user = await fetchUser(id)
return chain(addTimestamp, addStatus)(user)
}
// 使用
processUser(123).then(result => {
console.log(result)
})
數據驗證鏈
typescript
import { chain } from 'radash'
const validateEmail = (email: string) => {
if (!email.includes('@')) {
throw new Error('Invalid email format')
}
return email.toLowerCase()
}
const validateLength = (email: string) => {
if (email.length < 5) {
throw new Error('Email too short')
}
return email
}
const addDomain = (email: string) => {
if (!email.includes('.')) {
return email + '.com'
}
return email
}
const processEmail = chain(validateEmail, validateLength, addDomain)
try {
const result = processEmail('user@example')
console.log(result) // 'user@example.com'
} catch (error) {
console.error('Validation error:', error.message)
}
配置處理
typescript
import { chain } from 'radash'
const setDefaults = (config: any) => ({
port: 3000,
host: 'localhost',
debug: false,
...config
})
const validateConfig = (config: any) => {
if (config.port < 1 || config.port > 65535) {
throw new Error('Invalid port number')
}
return config
}
const addTimestamp = (config: any) => ({
...config,
createdAt: new Date().toISOString()
})
const processConfig = chain(setDefaults, validateConfig, addTimestamp)
const result = processConfig({ port: 8080, debug: true })
// 結果: { port: 8080, host: 'localhost', debug: true, createdAt: '2023-01-01T00:00:00.000Z' }
文本處理管道
typescript
import { chain } from 'radash'
const trim = (str: string) => str.trim()
const toLowerCase = (str: string) => str.toLowerCase()
const removeSpecialChars = (str: string) => str.replace(/[^a-z0-9\s]/g, '')
const normalizeSpaces = (str: string) => str.replace(/\s+/g, ' ')
const normalizeText = chain(trim, toLowerCase, removeSpecialChars, normalizeSpaces)
const result = normalizeText(' Hello, World! ')
// 步驟: ' Hello, World! ' -> 'Hello, World!' -> 'hello, world!' -> 'hello world' -> 'hello world'
// 結果: 'hello world'
注意事項
- 函數順序: 函數按從左到右的順序執行
- 類型安全: 所有函數必須接受和返回相同類型
- 錯誤處理: 鏈中的任何函數拋出錯誤都會中斷執行
- 性能: 每個函數都會創建新的值,不會修改原值
與其他函數的區別
chain
: 將多個函數鏈接在一起compose
: 從右到左組合函數pipe
: 從左到右組合函數flow
: 類似功能,但可能有不同的實現
性能
- 時間復雜度: O(n),其中 n 是函數數量
- 空間復雜度: O(n)
- 適用場景: 數據處理管道、函數組合