【发布时间】:2020-12-26 05:33:49
【问题描述】:
在我的架构中,我正在执行大量异步自定义验证。但是,验证的行为与我预期的不同。 即使 promise 解析为“false”,mongoose 仍会继续验证。根据their documentation,情况不应该如此。
示例架构:
var questSchema = mongoose.Schema({
questCategory: {
type: mongoose.Schema.Types.ObjectId,
required: true,
validate: {
validator: async function (v) {
await data_verificator.checkIfQuestCategoryExists(v);
},
message: (props) => `${props.value} is not a valid quest category id.`,
},
},
fulfillmentPeriod: {
type: String,
required: true,
validate: {
validator: async function (v) {
await data_verificator.checkFulfillmentPeriod(this.questCategory, v);
},
message: (props) =>
`${props.value} is an invalid value as it violates the limitations set by the quest category.`,
},
},
})
请注意,这两个架构字段的自定义验证异步发生。 questCategory 字段的验证工作得很好。如果 promise 解析为 false,则验证失败。但是,fulfillmentPeriod 字段并非如此。即使 promise 解析为 false,验证也会成功。
我不确定为什么会出现这种奇怪的行为。如果我将fulfillmentPeriod 的验证重写为如下所示,那么一切都会再次按预期工作。解析为false 的承诺会导致验证失败。这是为什么?为什么它适用于下面的代码,但不适用于我上面粘贴的初始代码?那是因为我引用了另一个异步验证的架构字段吗?
validator: async function (v) {
const result = await data_verificator.checkFulfillmentPeriod(this.questCategory, v);
return result;
},
以防万一这很重要,checkFulfillmentPeriod 函数如下所示:
const checkFulfillmentPeriod = async function (categoryId, period) {
const connectionManager = require("../configuration").connectionManager;
var category = await connectionManager.QuestCategoryModel.findOne({
_id: categoryId,
availableFulfillmentPeriods: {
$elemMatch: {
period: period,
},
},
});
if (!category) return false;
return true;
};
该函数只是检查是否有符合条件的类别。如果是,则返回 true。否则为假。根据我的发现,问题不在于这个函数,而是与 mongoose 的验证有关。
checkIfQuestCategoryExists函数看起来完全一样,只是查询设置不同。
我在这个问题上花了几个小时,现在我只是看不到任何错误。
如果能得到任何帮助/建议,我将不胜感激!
【问题讨论】:
-
验证触发时
this.questCategory的内容是什么? -
@raven 它是 MongoDB ObjectID。我在 checkFulfillmentPeriod 函数中使用了一个 console.log() 来测试它。
-
您是否尝试在此行添加返回?
await data_verificator.checkFulfillmentPeriod(this.questCategory, v); -
@raven yes :) 如果我写
return data_verificator.checkFulfillmentPeriod(this.questCategory, v)一切正常。应该是这样写的吗?他们的文档说明如下:如果您的验证器函数返回一个承诺(如异步函数),猫鼬将等待该承诺解决 - 这意味着我应该只返回未解决的承诺为猫鼬会自动等待它解决吗? -
问题是,如果你不写 return 就像你在返回一个 Promise
标签: javascript node.js mongodb mongoose mongoose-schema