函数组合是将多个纯函数校验器按顺序串联执行的校验模式,支持同步与异步融合、错误短路返回及统一结果结构,逻辑清晰、高度可复用。

函数组合是把多个校验函数像管道一样串起来,让数据依次通过每个校验步骤,最终得到统一的结果。它不依赖框架、不写重复 if-else,校验逻辑清晰可复用。
用纯函数定义原子校验规则
每个校验函数只做一件事:接收值,返回 { valid: boolean, message?: string }。比如:
- required:检查是否非空(字符串 trim 后长度 > 0,或数字/布尔不为 null/undefined)
- minLength(6):返回柯里化函数,校验字符串长度 ≥ 6
- email:用正则判断格式是否符合邮箱基本结构
- sameAs('password'):对比另一字段值(需传入完整表单数据)
组合多个校验函数成一个字段校验器
用 reduce 或自定义 compose 函数,从左到右执行。一旦某步 valid 为 false,直接返回该错误,不再继续:
- const validateName = compose(required, minLength(2), maxLength(20))
- const validateEmail = compose(required, email, uniqueInDB)
- 组合时保持顺序合理:先判空,再格式,最后异步或依赖其他字段的校验
统一处理字段级与表单级校验结果
对每个字段调用其组合校验器,收集全部结果;再用一个顶层函数汇总是否整体有效,并支持提取第一个错误或全部错误:
- 字段校验返回 { name: { valid, message } },表单校验返回 { valid: true, errors: {} } 或 { valid: false, errors: { email: '邮箱已存在' } }
- 错误信息可直接绑定到 UI,无需额外映射;新增校验只需加函数、改组合,不碰主流程
支持同步与异步校验自然融合
把 Promise 返回的校验函数(如 checkUsernameAvailable)也纳入组合链,用 async/composeAsync 或 await 链式调用:
- 同步校验走快速路径,异步校验自动等待,错误仍按同样结构返回
- 避免 callback 地狱,也不需要为异步单独设计两套校验接口
- 实际使用中可加 loading 状态控制,但校验逻辑本身不变











