# 异步校验

¥Asynchronous validation

你可以定义通过访问数据库或某些其他服务异步执行校验的格式和关键字。你应该在关键字或格式定义中添加 async: true(请参阅 addFormataddKeyword用户定义的关键字)。

¥You can define formats and keywords that perform validation asynchronously by accessing database or some other service. You should add async: true in the keyword or format definition (see addFormat, addKeyword and User-defined keywords).

如果你的结构使用异步格式/关键字或引用某些包含它们的结构,则它应该具有 "$async": true 关键字,以便 Ajv 可以正确编译它。如果在没有 $async 关键字的结构中使用异步格式/关键字或对异步结构的引用,Ajv 将在结构编译期间抛出异常。

¥If your schema uses asynchronous formats/keywords or refers to some schema that contains them it should have "$async": true keyword so that Ajv can compile it correctly. If asynchronous format/keyword or reference to asynchronous schema is used in the schema without $async keyword Ajv will throw an exception during schema compilation.

Use $async:true in referenced schemas

从当前或其他结构引用的所有异步子结构也应该具有 "$async": true 关键字,否则结构编译将失败。

¥All asynchronous subschemas that are referenced from the current or other schemas should have "$async": true keyword as well, otherwise the schema compilation will fail.

异步格式/关键字的校验函数应返回一个用 truefalse 解析的 promise(如果你想从关键字函数返回错误,则用 new Ajv.ValidationError(errors) 拒绝)。

¥Validation function for an asynchronous format/keyword should return a promise that resolves with true or false (or rejects with new Ajv.ValidationError(errors) if you want to return errors from the keyword function).

Ajv 将异步结构编译为 异步函数 (opens new window)。Node.js 7+ 和所有现代浏览器都支持异步函数。你可以通过 processCode 选项将转译器作为函数提供。参见 选项

¥Ajv compiles asynchronous schemas to async functions (opens new window). Async functions are supported in Node.js 7+ and all modern browsers. You can supply a transpiler as a function via processCode option. See Options.

编译的校验函数具有 $async: true 属性(如果结构是异步的),因此如果你同时使用同步和异步结构,则可以区分这些函数。

¥The compiled validation function has $async: true property (if the schema is asynchronous), so you can differentiate these functions if you are using both synchronous and asynchronous schemas.

校验结果将是一个 promise,该 promise 将使用经过校验的数据进行解析,或者使用包含 errors 属性中的校验错误数组的异常 Ajv.ValidationError 进行拒绝。

¥Validation result will be a promise that resolves with validated data or rejects with an exception Ajv.ValidationError that contains the array of validation errors in errors property.

示例:

¥Example:

const ajv = new Ajv()

ajv.addKeyword({
  keyword: "idExists",
  async: true,
  type: "number",
  validate: checkIdExists,
})

async function checkIdExists(schema, data) {
  // this is just an example, you would want to avoid SQL injection in your code
  const rows = await sql(`SELECT id FROM ${schema.table} WHERE id = ${data}`)
  return !!rows.length // true if record is found
}

const schema = {
  $async: true,
  properties: {
    userId: {
      type: "integer",
      idExists: {table: "users"},
    },
    postId: {
      type: "integer",
      idExists: {table: "posts"},
    },
  },
}

const validate = ajv.compile(schema)

validate({userId: 1, postId: 19})
  .then(function (data) {
    console.log("Data is valid", data) // { userId: 1, postId: 19 }
  })
  .catch(function (err) {
    if (!(err instanceof Ajv.ValidationError)) throw err
    // data is invalid
    console.log("Validation errors:", err.errors)
  })

# 使用转译器

¥Using transpilers

const ajv = new Ajv({processCode: transpileFunc})
const validate = ajv.compile(schema) // transpiled es7 async function
validate(data).then(successFunc).catch(errorFunc)

参见 选项

¥See Options.