Skip to content

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'

注意事项

  1. 函数顺序: 函数按从左到右的顺序执行
  2. 类型安全: 所有函数必须接受和返回相同类型
  3. 错误处理: 链中的任何函数抛出错误都会中断执行
  4. 性能: 每个函数都会创建新的值,不会修改原值

与其他函数的区别

  • chain: 将多个函数链接在一起
  • compose: 从右到左组合函数
  • pipe: 从左到右组合函数
  • flow: 类似功能,但可能有不同的实现

性能

  • 时间复杂度: O(n),其中 n 是函数数量
  • 空间复杂度: O(n)
  • 适用场景: 数据处理管道、函数组合

Released under the MIT License.