compose
组合多个函数,创建函数管道。
基础用法
typescript
import { compose } from 'radash'
const addOne = (x: number) => x + 1
const double = (x: number) => x * 2
const square = (x: number) => x * x
const composed = compose(addOne, double, square)
const result = composed(3)
// 计算过程: square(3) = 9, double(9) = 18, addOne(18) = 19
console.log(result) // 19
语法
typescript
function compose<T extends any[], U>(
...fns: ((...args: T) => U)[]
): (...args: T) => U
参数
...fns
(function[]): 要组合的函数数组
返回值
返回一个组合后的函数,从右到左执行。
示例
基本函数组合
typescript
import { compose } from 'radash'
const toUpperCase = (str: string) => str.toUpperCase()
const addExclamation = (str: string) => str + '!'
const repeat = (str: string) => str + str
const shout = compose(addExclamation, toUpperCase, repeat)
const result = shout('hello')
// 计算过程: repeat('hello') = 'hellohello', toUpperCase('hellohello') = 'HELLOHELLO', addExclamation('HELLOHELLO') = 'HELLOHELLO!'
console.log(result) // 'HELLOHELLO!'
处理数组
typescript
import { compose } 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((acc, x) => acc + x, 0)
const processNumbers = compose(sum, double, filterEven)
const result = processNumbers([1, 2, 3, 4, 5, 6])
// 计算过程: filterEven([1,2,3,4,5,6]) = [2,4,6], double([2,4,6]) = [4,8,12], sum([4,8,12]) = 24
console.log(result) // 24
处理对象
typescript
import { compose } from 'radash'
const getUsers = (data: any) => data.users
const filterActive = (users: any[]) => users.filter(user => user.active)
const mapNames = (users: any[]) => users.map(user => user.name)
const joinNames = (names: string[]) => names.join(', ')
const getActiveUserNames = compose(joinNames, mapNames, filterActive, getUsers)
const data = {
users: [
{ id: 1, name: 'Alice', active: true },
{ id: 2, name: 'Bob', active: false },
{ id: 3, name: 'Charlie', active: true },
{ id: 4, name: 'Diana', active: true }
]
}
const result = getActiveUserNames(data)
console.log(result) // 'Alice, Charlie, Diana'
处理字符串
typescript
import { compose } from 'radash'
const trim = (str: string) => str.trim()
const toLowerCase = (str: string) => str.toLowerCase()
const replaceSpaces = (str: string) => str.replace(/\s+/g, '-')
const addPrefix = (str: string) => `slug-${str}`
const createSlug = compose(addPrefix, replaceSpaces, toLowerCase, trim)
const result = createSlug(' Hello World ')
// 计算过程: trim(' Hello World ') = 'Hello World', toLowerCase('Hello World') = 'hello world', replaceSpaces('hello world') = 'hello-world', addPrefix('hello-world') = 'slug-hello-world'
console.log(result) // 'slug-hello-world'
处理数字
typescript
import { compose } from 'radash'
const add = (a: number) => (b: number) => a + b
const multiply = (a: number) => (b: number) => a * b
const square = (x: number) => x * x
const complexCalculation = compose(
square,
multiply(3),
add(5)
)
const result = complexCalculation(2)
// 计算过程: add(5)(2) = 7, multiply(3)(7) = 21, square(21) = 441
console.log(result) // 441
处理类型转换
typescript
import { compose } from 'radash'
const parseNumber = (str: string) => parseInt(str, 10)
const addTen = (num: number) => num + 10
const double = (num: number) => num * 2
const toString = (num: number) => num.toString()
const processString = compose(toString, double, addTen, parseNumber)
const result = processString('15')
// 计算过程: parseNumber('15') = 15, addTen(15) = 25, double(25) = 50, toString(50) = '50'
console.log(result) // '50'
处理验证和转换
typescript
import { compose } from 'radash'
const validateEmail = (email: string) => {
if (!email.includes('@')) {
throw new Error('Invalid email')
}
return email
}
const normalizeEmail = (email: string) => email.toLowerCase().trim()
const addDomain = (email: string) => email.includes('@') ? email : email + '@example.com'
const processEmail = compose(addDomain, normalizeEmail, validateEmail)
try {
const result = processEmail(' USER@EXAMPLE.COM ')
console.log(result) // 'user@example.com'
} catch (error) {
console.error('Error:', error.message)
}
处理异步函数
typescript
import { compose } from 'radash'
const fetchUser = async (id: number) => {
const response = await fetch(`/api/users/${id}`)
return response.json()
}
const extractName = (user: any) => user.name
const toUpperCase = (name: string) => name.toUpperCase()
const getUserName = compose(toUpperCase, extractName, fetchUser)
// 注意:由于fetchUser是异步的,这个组合函数也会返回Promise
const result = await getUserName(1)
console.log(result) // 'ALICE'
处理条件逻辑
typescript
import { compose } from 'radash'
const isEven = (num: number) => num % 2 === 0
const double = (num: number) => num * 2
const addOne = (num: number) => num + 1
const processNumber = compose(
(num: number) => isEven(num) ? double(num) : addOne(num),
(num: number) => num * 3
)
console.log(processNumber(4)) // 24 (4是偶数,double(4)=8, 8*3=24)
console.log(processNumber(5)) // 18 (5是奇数,addOne(5)=6, 6*3=18)
处理错误处理
typescript
import { compose } from 'radash'
const safeParse = (str: string) => {
try {
return JSON.parse(str)
} catch {
return null
}
}
const extractName = (data: any) => data?.name || 'Unknown'
const toUpperCase = (name: string) => name.toUpperCase()
const processData = compose(toUpperCase, extractName, safeParse)
console.log(processData('{"name": "alice"}')) // 'ALICE'
console.log(processData('invalid json')) // 'UNKNOWN'
处理管道操作
typescript
import { compose } from 'radash'
const filterNumbers = (arr: any[]) => arr.filter(x => typeof x === 'number')
const double = (arr: number[]) => arr.map(x => x * 2)
const sum = (arr: number[]) => arr.reduce((acc, x) => acc + x, 0)
const formatResult = (num: number) => `Total: ${num}`
const processArray = compose(formatResult, sum, double, filterNumbers)
const mixedArray = [1, 'hello', 2, 'world', 3, true, 4]
const result = processArray(mixedArray)
// 计算过程: filterNumbers([1,'hello',2,'world',3,true,4]) = [1,2,3,4], double([1,2,3,4]) = [2,4,6,8], sum([2,4,6,8]) = 20, formatResult(20) = 'Total: 20'
console.log(result) // 'Total: 20'
处理复杂对象转换
typescript
import { compose } from 'radash'
interface User {
id: number
name: string
email: string
age: number
}
const getUsers = (data: any) => data.users || []
const filterAdults = (users: User[]) => users.filter(user => user.age >= 18)
const mapNames = (users: User[]) => users.map(user => user.name)
const sortNames = (names: string[]) => names.sort()
const joinNames = (names: string[]) => names.join(', ')
const getAdultUserNames = compose(joinNames, sortNames, mapNames, filterAdults, getUsers)
const data = {
users: [
{ id: 1, name: 'Alice', email: 'alice@example.com', age: 25 },
{ id: 2, name: 'Bob', email: 'bob@example.com', age: 16 },
{ id: 3, name: 'Charlie', email: 'charlie@example.com', age: 30 },
{ id: 4, name: 'Diana', email: 'diana@example.com', age: 22 }
]
}
const result = getAdultUserNames(data)
console.log(result) // 'Alice, Charlie, Diana'
处理数学计算
typescript
import { compose } from 'radash'
const add = (a: number) => (b: number) => a + b
const multiply = (a: number) => (b: number) => a * b
const subtract = (a: number) => (b: number) => b - a
const square = (x: number) => x * x
const complexMath = compose(
square,
multiply(2),
add(10),
subtract(5)
)
const result = complexMath(3)
// 计算过程: subtract(5)(3) = -2, add(10)(-2) = 8, multiply(2)(8) = 16, square(16) = 256
console.log(result) // 256
注意事项
- 执行顺序: 函数从右到左执行
- 类型安全: 确保函数参数和返回值类型匹配
- 性能: 组合函数会创建新的函数,注意内存使用
- 调试: 组合函数可能难以调试,建议添加日志
- 错误处理: 确保中间函数能正确处理错误
与其他方法的区别
pipe()
: 从左到右执行函数compose()
: 从右到左执行函数- 手动调用: 需要嵌套函数调用
实际应用场景
- 数据处理: 组合多个数据转换步骤
- 字符串处理: 组合多个字符串操作
- 数学计算: 组合多个数学运算
- 验证逻辑: 组合多个验证步骤
- 格式化: 组合多个格式化操作