NodeJS + Validate.js多个异步验证器

时间:2018-11-01 11:49:34

标签: javascript node.js promise validate.js

我对NodeJS有点陌生,我想对两个字段使用自定义异步验证器。我使用异步验证程序的原因是必须向数据库发出请求,以检查是否已存在具有该ID的记录。我实现了两个验证器(下面列出的代码)-如果在validate.async约束中仅使用其中一个,则每个验证器都可以工作。但是,如果我同时使用它们,则会抛出未处理的承诺拒绝(也在下面给出确切的错误),并且仅返回第一个验证者的错误。

代码: timezoneValidateAsync:

function valAsync(value) {
    return new validate.Promise(async function(resolve, reject) {
      const timezone = await Timezone.findById(value);
      if (!timezone) {
        reject(ValidationErrors.NOSUCHTIMEZONE);
      }
      resolve();
    });
  }

  validate.validators.timezoneValidateAsync = valAsync;

languageValidateAsync:

function valAsync(value) {
    return new validate.Promise(async function(resolve, reject) {
      const language = await Language.findById(value);
      if (!language) {
        reject(ValidationErrors.NOSUCHLANGUAGE);
      }

      resolve();
    });
  }

  validate.validators.languageValidateAsync = valAsync;

validate.async中的用法:

constraints = {
      timezoneId: {
        presence: {
          message: ValidationErrors.TIMEZONEIDEXISTS
        },
        numericality: {
          greaterThan: 0,
          message: ValidationErrors.TIMEZONEIDGREATERTHANZERO
        },
        timezoneValidateAsync: {}
      },
      languageId: {
        presence: {
          message: ValidationErrors.LANGUAGEIDEXISTS
        },
        numericality: {
          greaterThan: 0,
          message: ValidationErrors.LANGUAGEIDGREATERTHANZERO
        },
        languageValidateAsync: {}
      }
    };

validate.async({
        timezoneId: fpreferencesDS.timezoneId,
        languageId: fpreferencesDS.languageId
      }, constraints).then(() => {
        next();
      }, errors => {
        console.log(errors);
        return;
      });

如果我注释掉timezoneValidateAsync验证器,则在errors变量中可以很好地返回语言错误。如果我注释掉languageValidateAsync,则可以正确返回时区错误。如果我对它们都未加注释,则会抛出以下未处理的承诺拒绝:

  

(节点:25280)UnhandledPromiseRejectionWarning:#(节点:25280)   UnhandledPromiseRejectionWarning:未处理的承诺拒绝。这个   由抛出异步函数引起的错误   没有障碍,或者拒绝了没有处理的承诺   使用.catch()。 (拒绝ID:1)(节点:25280)[DEP0018]   DeprecationWarning:已弃用未处理的承诺拒绝。在   未来,未处理的承诺拒绝将终止   具有非零退出代码的Node.js进程。

我想我的错误在于以某种方式链接了这些诺言,但我真的不知道如何实现(如果我是对的话)。我愿意接受任何建议,想法和指示。

1 个答案:

答案 0 :(得分:0)

我发现了自己的错误,事实证明,如果出现错误,我不应该拒绝诺言。相反,我应该用错误消息解决它。示例(适用于两个验证器):

if (!timezone) {
   resolve(ValidationErrors.NOSUCHTIMEZONE);
   return;
}

代替

if (!timezone) {
   reject(ValidationErrors.NOSUCHTIMEZONE);
   return;
}