async-validator 核心 API 与使用指南

async-validator 核心 API 与使用指南

【免费下载链接】async-validator validate form asynchronous 【免费下载链接】async-validator 项目地址: https://gitcode.com/gh_mirrors/as/async-validator

async-validator 是一个强大的表单验证库,本文深入解析其核心 API 和使用方法。重点介绍 Schema 类的构造函数与规则定义机制,包括规则数据结构、定义示例、处理流程和错误处理机制,帮助开发者构建复杂的验证逻辑。

Schema 类的构造函数与规则定义

async-validator 的核心是 Schema 类,它负责封装验证规则并执行数据验证。Schema 类的构造函数是整个验证流程的起点,它接收一个描述符对象来定义验证规则。理解构造函数的内部机制和规则定义方式对于高效使用 async-validator 至关重要。

Schema 构造函数详解

Schema 类的构造函数接收一个 descriptor 参数,该参数是一个包含验证规则的对象。构造函数的主要作用是初始化验证规则,并通过 define 方法将规则转换为内部格式。

class Schema {
  rules: Record<string, RuleItem[]> = null;
  _messages: InternalValidateMessages = defaultMessages;

  constructor(descriptor: Rules) {
    this.define(descriptor);
  }

构造函数的工作流程可以用以下流程图表示:

mermaid

规则定义机制

define 方法是 Schema 类的核心方法,负责解析和规范化验证规则:

define(rules: Rules) {
  if (!rules) {
    throw new Error('Cannot configure a schema with no rules');
  }
  if (typeof rules !== 'object' || Array.isArray(rules)) {
    throw new Error('Rules must be an object');
  }
  this.rules = {};

  Object.keys(rules).forEach(name => {
    const item: Rule = rules[name];
    this.rules[name] = Array.isArray(item) ? item : [item];
  });
}

规则数据结构

async-validator 支持多种类型的规则定义,每种规则都有特定的属性和验证逻辑。以下是主要的规则类型和属性:

规则属性类型描述适用类型
typeRuleType字段类型验证所有类型
requiredboolean是否必填所有类型
patternRegExp \| string正则表达式匹配string
minnumber最小值/最小长度number, string, array
maxnumber最大值/最大长度number, string, array
lennumber精确长度/数值number, string, array
enumArray<any>枚举值验证enum
whitespaceboolean空白字符验证string
fieldsRecord<string, Rule>嵌套字段规则object, array
defaultFieldRule默认字段规则object, array
transformfunction值转换函数所有类型
validatorfunction自定义同步验证器所有类型
asyncValidatorfunction自定义异步验证器所有类型

规则定义示例

基本规则定义
// 单个规则定义
const descriptor = {
  username: {
    type: 'string',
    required: true,
    min: 3,
    max: 20,
    message: '用户名长度必须在3-20个字符之间'
  }
};

// 多个规则组合
const descriptor = {
  email: [
    { type: 'string', required: true },
    { type: 'email', message: '请输入有效的邮箱地址' },
    { 
      asyncValidator: async (rule, value) => {
        // 异步验证邮箱是否已注册
        const exists = await checkEmailExists(value);
        if (exists) {
          throw new Error('该邮箱已被注册');
        }
      }
    }
  ]
};
嵌套对象验证
const descriptor = {
  user: {
    type: 'object',
    required: true,
    fields: {
      name: { type: 'string', required: true },
      age: { type: 'number', min: 18, max: 100 },
      address: {
        type: 'object',
        fields: {
          city: { type: 'string', required: true },
          street: { type: 'string' }
        }
      }
    }
  }
};
数组验证
const descriptor = {
  tags: {
    type: 'array',
    required: true,
    min: 1,
    max: 5,
    defaultField: { type: 'string', min: 2 }
  },
  scores: {
    type: 'array',
    required: true,
    len: 3,
    fields: {
      0: { type: 'number', min: 0, max: 100 },
      1: { type: 'number', min: 0, max: 100 },
      2: { type: 'number', min: 0, max: 100 }
    }
  }
};

规则处理流程

当 Schema 构造函数处理规则描述符时,会经历以下处理流程:

mermaid

错误处理机制

在规则定义阶段,Schema 类会进行严格的参数验证:

  1. 空规则检查:如果传入的 descriptor 为 null 或 undefined,抛出错误
  2. 类型检查:确保 descriptor 是一个普通对象,不是数组
  3. 规则标准化:将单个规则项转换为数组格式,确保统一处理

最佳实践

  1. 规则组织:将相关字段的规则分组,提高代码可读性
  2. 错误消息:为每个规则提供明确的错误消息,方便用户理解
  3. 异步验证:对于需要网络请求的验证,使用 asyncValidator
  4. 性能考虑:避免在验证器中执行昂贵的操作,必要时使用缓存
  5. 类型安全:充分利用 TypeScript 的类型系统,确保规则定义的正确性

通过深入了解 Schema 类的构造函数和规则定义机制,开发者可以更有效地构建复杂的验证逻辑,确保应用程序数据的完整性和一致性。

validate 方法的多种调用方式

async-validator 的 validate 方法提供了多种灵活的调用方式,以适应不同的开发场景和编程风格。无论是传统的回调模式、现代的 Promise 模式,还是同步验证需求,都能找到合适的调用方式。

回调函数模式

回调函数模式是最传统的异步验证方式,适合在 Node.js 环境或需要处理复杂异步流程的场景中使用。

import Schema from 'async-validator';

const descriptor = {
  username: {
    type: 'string',
    required: true,
    min: 3,
    max: 20
  },
  email: {
    type: 'email',
    required: true
  }
};

const validator = new Schema(descriptor);

// 回调函数调用方式
validator.validate({ username: 'john', email: 'john@example.com' }, (errors, fields) => {
  if (errors) {
    // 验证失败处理
    console.log('验证错误:', errors);
    console.log('字段错误:', fields);
    return;
  }
  // 验证成功
  console.log('验证通过');
});

回调函数接收两个参数:

  • errors: 包含所有验证错误的数组
  • fields: 按字段名组织的错误对象

Promise 模式

Promise 模式是现代 JavaScript 开发的首选方式,支持链式调用和 async/await 语法。

// Promise 调用方式
validator.validate({ username: 'john', email: 'john@example.com' })
  .then(() => {
    console.log('验证通过');
  })
  .catch(({ errors, fields }) => {
    console.log('验证失败:', errors);
    console.log('字段错误详情:', fields);
  });

// 使用 async/await
async function validateUser(userData) {
  try {
    await validator.validate(userData);
    console.log('用户数据验证通过');
    return true;
  } catch (error) {
    console.log('验证错误:', error.errors);
    return false;
  }
}

混合调用模式

validate 方法支持重载,可以根据参数类型自动选择调用方式:

// 方式1: 只传数据源
validator.validate(data); // 返回 Promise

// 方式2: 数据源 + 回调函数  
validator.validate(data, callback); // 使用回调

// 方式3: 数据源 + 选项 + 回调函数
validator.validate(data, options, callback);

// 方式4: 数据源 + 选项
validator.validate(data, options); // 返回 Promise

配置选项的使用

validate 方法支持多种配置选项来定制验证行为:

const options = {
  first: true, // 遇到第一个错误就停止验证
  firstFields: ['email'], // 对指定字段遇到第一个错误就停止
  suppressWarning: false, // 是否抑制警告
  messages: { // 自定义错误消息
    required: '字段 {field} 是必填的',
    string: '{field} 必须是字符串'
  }
};

// 带选项的验证
validator.validate(userData, options, (errors, fields) => {
  // 处理结果
});

// 或使用 Promise
validator.validate(userData, options)
  .then(/* ... */)
  .catch(/* ... */);

验证流程示意图

以下是 validate 方法的执行流程:

mermaid

错误处理对比

不同调用方式的错误处理对比:

调用方式成功处理失败处理适用场景
回调函数callback(null, data)callback(errors, fields)传统 Node.js 项目
Promise.then().catch({errors, fields})现代前端/Node.js
async/awaittrycatchES2017+ 项目

实际应用示例

// 表单验证示例
const formValidator = new Schema({
  name: { type: 'string', required: true },
  age: { type: 'number', min: 18, max: 100 },
  email: { type: 'email', required: true },
  password: { type: 'string', min: 6 }
});

// 提交表单时的验证
async function handleSubmit(formData) {
  try {
    await formValidator.validate(formData, {
      first: true // 快速失败模式
    });
    
    // 验证通过,提交数据
    await submitToServer(formData);
    showSuccess('表单提交成功');
    
  } catch (error) {
    // 显示第一个错误信息
    if (error.errors && error.errors.length > 0) {
      showError(error.errors[0].message);
    }
  }
}

// 实时验证示例
function setupRealTimeValidation() {
  const emailInput = document.getElementById('email');
  
  emailInput.addEventListener('blur', async () => {
    try {
      await formValidator.validate({ email: emailInput.value }, {
        keys: ['email'] // 只验证 email 字段
      });
      showFieldValid('email');
    } catch (error) {
      showFieldInvalid('email', error.errors[0].message);
    }
  });
}

性能优化建议

对于大型表单或性能敏感的场景,可以考虑以下优化策略:

  1. 使用 first: true:在用户提交时快速失败,只返回第一个错误
  2. 按需验证:使用 keys 选项只验证特定字段
  3. 避免重复创建:复用 Schema 实例而不是每次创建新实例
  4. 延迟验证:对非关键字段使用防抖验证
// 性能优化示例
const optimizedValidator = new Schema(/* ... */);

// 只验证必要字段
function validateCriticalFields(data) {
  return optimizedValidator.validate(data, {
    keys: ['email', 'password'], // 只验证关键字段
    first: true // 快速失败
  });
}

通过灵活运用 validate 方法的各种调用方式,可以根据项目需求选择最合适的验证策略,既保证代码的可读性,又确保良好的性能表现。

验证选项配置与错误处理策略

async-validator 提供了丰富的验证选项配置和灵活的错误处理机制,让开发者能够根据不同的业务场景定制验证行为。本节将深入探讨验证选项的配置方法、错误消息的自定义策略以及各种错误处理的最佳实践。

验证选项配置详解

async-validator 的 ValidateOption 接口定义了完整的验证配置选项,这些选项可以在调用 validate 方法时传入:

interface ValidateOption {
  // 是否抑制内部警告
  suppressWarning?: boolean;
  
  // 是否抑制验证器错误
  suppressValidatorError?: boolean;
  
  // 当第一个验证规则产生错误时停止处理
  first?: boolean;
  
  // 当指定字段的第一个验证规则产生错误时停止该字段的处理
  firstFields?: boolean | string[];
  
  // 自定义错误消息
  messages?: Partial<ValidateMessages>;
  
  // 需要触发的规则名称
  keys?: string[];
  
  // 自定义错误处理函数
  error?: (rule: InternalRuleItem, message: string) => ValidateError;
}
验证流程控制选项

first 选项:当设置为 true 时,一旦某个验证规则产生错误,整个验证过程立即停止,不再继续验证其他规则。这在需要快速失败验证的场景中非常有用。

const validator = new Schema({
  username: { type: 'string', required: true },
  email: { type: 'email', required: true },
  password: { type: 'string', min: 6 }
});

// 只返回第一个错误
validator.validate(formData, { first: true }, (errors) => {
  // 如果username验证失败,email和password将不会被验证
});

firstFields 选项:更细粒度的控制,可以指定在哪些字段上启用快速失败验证:

// 所有字段都启用快速失败
validator.validate(formData, { firstFields: true });

// 只在特定字段上启用快速失败
validator.validate(formData, { firstFields: ['username', 'email'] });
错误抑制选项

suppressWarning:抑制内部警告信息,适用于生产环境。

suppressValidatorError:抑制验证器错误,当自定义验证器抛出异常时不会中断验证流程。

错误消息自定义策略

async-validator 提供了完整的错误消息自定义机制,支持多语言和个性化的错误提示。

默认错误消息结构

系统内置了完整的错误消息模板:

const defaultMessages = {
  default: 'Validation error on field %s',
  required: '%s is required',
  enum: '%s must be one of %s',
  whitespace: '%s cannot be empty',
  types: {
    string: '%s is not a %s',
    number: '%s is not a %s',
    // ... 其他类型
  },
  string: {
    len: '%s must be exactly %s characters',
    min: '%s must be at least %s characters',
    max: '%s cannot be longer than %s characters',
    range: '%s must be between %s and %s characters',
  },
  // ... 其他消息类型
};
自定义错误消息

可以通过多种方式自定义错误消息:

全局消息覆盖

import Schema from 'async-validator';

// 全局覆盖默认消息
Schema.messages({
  required: '请填写%s字段',
  string: {
    min: '%s至少需要%s个字符'
  }
});

实例级别消息配置

const validator = new Schema(rules);
validator.messages({
  required: '该字段是必填项',
  email: '请输入有效的邮箱地址'
});

// 或者在验证时传入
validator.validate(data, {
  messages: {
    required: '必填字段不能为空'
  }
});

规则级别消息定制

const rules = {
  username: {
    type: 'string',
    required: true,
    message: '用户名不能为空', // 字段级别的自定义消息
    min: 6,
    message: '用户名长度不能少于6位' // 覆盖min规则的默认消息
  },
  email: {
    type: 'email',
    required: true,
    message: (field) => `${field}格式不正确` // 函数式消息
  }
};

错误处理最佳实践

错误数据结构

验证失败时返回的错误数据具有统一的结构:

interface ValidateError {
  message?: string;        // 错误消息
  fieldValue?: any;        // 字段值
  field?: string;          // 字段名
}

type ValidateFieldsError = Record<string, ValidateError[]>;
同步错误处理
validator.validate(formData, (errors, fields) => {
  if (errors) {
    // errors: ValidateError[] - 所有错误的数组
    // fields: ValidateFieldsError - 按字段分组的错误对象
    
    errors.forEach(error => {
      console.log(`字段 ${error.field}: ${error.message}`);
      console.log(`当前值: ${error.fieldValue}`);
    });
    
    // 或者按字段处理
    Object.keys(fields).forEach(fieldName => {
      fields[fieldName].forEach(error => {
        console.log(`${fieldName}字段错误: ${error.message}`);
      });
    });
  }
});
Promise 错误处理
validator.validate(formData)
  .then(() => {
    // 验证通过
  })
  .catch(({ errors, fields }) => {
    // 统一的错误处理
    this.handleValidationErrors(errors, fields);
  });

// 统一的错误处理方法
handleValidationErrors(errors, fields) {
  const errorMap = new Map();
  
  errors.forEach(error => {
    if (!errorMap.has(error.field)) {
      errorMap.set(error.field, []);
    }
    errorMap.get(error.field).push(error.message);
  });
  
  // 更新UI显示错误
  this.updateFormErrors(errorMap);
}
高级错误处理模式

错误转换与格式化

function formatErrors(errors) {
  return errors.reduce((acc, error) => {
    const key = error.field;
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push({
      message: error.message,
      value: error.fieldValue,
      type: this.getErrorType(error.message)
    });
    return acc;
  }, {});
}

function getErrorType(message) {
  if (message.includes('required')) return 'required';
  if (message.includes('pattern')) return 'pattern';
  if (message.includes('min') || message.includes('max')) return 'range';
  return 'default';
}

条件错误处理

validator.validate(data, {
  error: (rule, message) => {
    // 自定义错误对象创建
    return {
      message: this.translateMessage(message, rule.field),
      field: rule.field,
      fieldValue: data[rule.field],
      severity: this.getErrorSeverity(rule),
      timestamp: Date.now()
    };
  }
});

验证流程的图表表示

以下是 async-validator 验证选项配置与错误处理的完整流程:

mermaid

配置选项对比表

下表总结了各种验证选项的使用场景和效果:

选项类型默认值描述使用场景
firstbooleanfalse第一个错误时停止验证快速失败验证
firstFieldsboolean/string[]false字段级别快速失败关键字段优先验证
suppressWarningbooleanfalse抑制警告信息生产环境
suppressValidatorErrorbooleanfalse抑制验证器错误容错性要求高的场景
messagesobjectnull自定义错误消息多语言支持、个性化提示
keysstring[]null指定验证字段部分字段验证
errorfunctionnull自定义错误创建高级错误处理

实战示例:完整的验证配置

// 复杂的验证配置示例
const advancedOptions = {
  first: true, // 快速失败
  suppressWarning: process.env.NODE_ENV === 'production', // 生产环境抑制警告
  messages: {
    required: '${field}是必填项',
    string: {
      min: '${field}至少需要${min}个字符',
      max: '${field}不能超过${max}个字符'
    }
  },
  error: (rule, message) => {
    // 增强错误信息
    return {
      message: `${message} (代码: ${rule.field.toUpperCase()}_ERR)`,
      field: rule.field,
      code: `${rule.field.toUpperCase()}_ERROR`,
      timestamp: new Date().toISOString(),
      severity: 'error'
    };
  }
};

// 执行验证
try {
  await validator.validate(formData, advancedOptions);
  console.log('验证通过');
} catch ({ errors }) {
  // 处理增强的错误信息
  errors.forEach(error => {
    console.error(`[${error.code}] ${error.message} at ${error.timestamp}`);
    this.notifyError(error);
  });
}

通过合理配置验证选项和采用适当的错误处理策略,async-validator 能够满足各种复杂的业务验证需求,从简单的表单验证到复杂的企业级应用验证场景都能游刃有余。

Promise 与回调函数的兼容使用

async-validator 作为一个现代化的表单验证库,在设计时就充分考虑了不同开发者的使用习惯,提供了 Promise 和回调函数两种使用方式的完美兼容。这种设计使得无论是习惯于传统回调风格的开发者,还是偏好现代 Promise/async-await 语法的开发者,都能以自己熟悉的方式使用这个库。

核心兼容机制

async-validator 通过方法重载和类型检测实现了两种使用方式的智能识别。在 validate 方法的实现中,它会根据传入参数的类型自动判断应该使用哪种处理方式:

// 方法重载签名
validate(source: Values, option?: ValidateOption, callback?: ValidateCallback): Promise<Values>;
validate(source: Values, callback: ValidateCallback): Promise<Values>;
validate(source: Values): Promise<Values>;

// 实际实现
validate(source_: Values, o: any = {}, oc: any = () => {}): Promise<Values> {
  let source: Values = source_;
  let options: ValidateOption = o;
  let callback: ValidateCallback = oc;
  
  // 智能参数检测
  if (typeof options === 'function') {
    callback = options;
    options = {};
  }
  
  // 统一的验证逻辑处理...
}

回调函数使用方式

传统的回调函数方式是 async-validator 的基础支持模式,适合在 Node.js 环境或需要向后兼容的场景中使用:

const validator = new Schema({
  username: { type: 'string', required: true, min: 3 },
  email: { type: 'email', required: true }
});

// 使用回调函数
validator.validate({ username: 'john', email: 'john@example.com' }, (errors, fields) => {
  if (errors) {
    console.log('验证失败:', errors);
    // 处理错误逻辑
    return;
  }
  console.log('验证通过');
  // 继续业务逻辑
});

Promise 使用方式

对于现代 JavaScript 开发,async-validator 提供了完整的 Promise 支持,可以使用 .then()/.catch() 或 async/await 语法:

// 使用 .then()/.catch()
validator.validate({ username: 'john', email: 'john@example.com' })
  .then((validData) => {
    console.log('验证通过:', validData);
    // 处理成功逻辑
  })
  .catch(({ errors, fields }) => {
    console.log('验证失败:', errors);
    // 处理错误逻辑
  });

// 使用 async/await
async function validateUser(data) {
  try {
    const result = await validator.validate(data);
    console.log('验证通过:', result);
    return result;
  } catch (error) {
    console.log('验证失败:', error.errors);
    throw error;
  }
}

混合验证器中的兼容处理

async-validator 在处理同步验证器和异步验证器时,也保持了 Promise 和回调的兼容性:

const descriptor = {
  name: {
    type: 'string',
    required: true,
    // 同步验证器 - 返回 boolean 或错误
    validator: (rule, value) => value === 'muji',
  },
  age: {
    type: 'number',
    // 异步验证器 - 返回 Promise
    asyncValidator: (rule, value) => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (value < 18) {
            reject('too young');
          } else {
            resolve();
          }
        }, 100);
      });
    },
  },
};

错误处理的一致性

无论使用哪种方式,错误处理都保持一致的格式:

// 回调方式的错误格式
validator.validate(data, (errors, fields) => {
  if (errors) {
    // errors: ValidateError[] - 所有错误的数组
    // fields: ValidateFieldsError - 按字段分组的错误对象
  }
});

// Promise 方式的错误格式
validator.validate(data).catch(({ errors, fields }) => {
  // 同样的错误结构,便于统一处理
});

性能与内存考虑

async-validator 在内部使用统一的验证引擎,无论外部使用回调还是 Promise,内部处理逻辑都是相同的,不会因为使用方式的不同而产生性能差异。这种设计确保了:

  1. 内存效率:避免为不同使用方式创建重复的逻辑
  2. 性能一致:验证速度不受使用方式影响
  3. 代码复用:核心验证逻辑只需实现一次

使用建议

根据不同的场景选择合适的用法:

使用场景推荐方式理由
Node.js 传统项目回调函数更好的与现有代码风格集成
现代前端应用Promise/async-await更好的可读性和错误处理
混合环境任意选择async-validator 完美兼容两者
需要链式调用Promise便于组合多个验证操作

mermaid

这种设计体现了 async-validator 作为现代化库的深思熟虑,既保留了传统的兼容性,又拥抱了现代 JavaScript 的发展趋势,为开发者提供了最大的灵活性和便利性。

总结

async-validator 提供了灵活且强大的验证功能,支持多种调用方式(回调和 Promise)和丰富的配置选项。通过 Schema 类定义规则,validate 方法执行验证,并支持错误消息自定义和高级错误处理。该库兼顾传统和现代开发需求,是确保数据完整性和一致性的理想选择。

【免费下载链接】async-validator validate form asynchronous 【免费下载链接】async-validator 项目地址: https://gitcode.com/gh_mirrors/as/async-validator

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值