【问题标题】:Avoid using nested promise for validation避免使用嵌套的 promise 进行验证
【发布时间】:2020-08-24 17:48:58
【问题描述】:

我正在使用 node 和 mongoDB 创建后端服务。

我确实有如下架构:

const UserSchema = new Schema({
    name : {
        type : String,
        required : true
    },
    email : {
        type : String,
        required : true
    },
    phoneNo : {
        type : Number,
        required : true
    },
    password : {
        type : String,
        required : true
    },
    avatar : {
        type : String
    },
    date  : {
        type : Date,
        default : Date.now()
    }
})

现在我想验证电话号码和电子邮件是否存在。对于此检查,我有以下代码 sn-p :


User.findOne({ email : req.body.email })
        .then(user => {
            if (user){ 
                errors.email = 'Email already exists';
                return res.status(400).json(errors);
            } else {
                User.findOne( {phoneNo : req.body.phoneNo})
                .then (user => {
                    if(user) {
                        errors.phoneNo = 'Phone no already exists';
                        return res.status(400).json(errors);
                    }
                    else {
                    .....

所以我使用的是嵌套承诺。我相信这不是一个好的做法。但我需要为不同的点显示不同的验证消息。这可以通过更简单的方式实现吗?

【问题讨论】:

    标签: javascript node.js mongodb performance mongoose


    【解决方案1】:

    您可以使用async/await,这将使您的代码更简单、更易于推理。

    async function main() {
        const existingByEmail = await User.findOne({ email: req.body.email });
    
        if (existingByEmail) {
            errors.email = "Email already exists";
            return res.status(400).json(errors);
        }
    
        const existingByPhone = await User.findOne({ phoneNo: req.body.phoneNo });
    
        if (existingByPhone) {
            errors.phoneNo = "Phone no already exists";
            return res.status(400).json(errors);
        }
    }
    

    【讨论】:

    • 其实我不想要异步等待结构。我要简化操作,不容易写代码。
    • @SoumyaKantiNaskar “所以我正在使用嵌套的 Promise。我认为这不是一个好的做法。这可以通过更简单的方式实现吗?”
    【解决方案2】:

    您可以将 email 和 phoneNo 设置为唯一(推荐)并检查 mongoose 处理的重复错误。

        email : {
            type : String,
            required : true,
            unique : true // add unique option
        },
        phoneNo : {
            type : Number,
            required : true,
            unique : true // add unique option
        },
    

    这个包mongoose-unique-validator 将返回触发重复错误的字段。但是你也可以按照here的建议自己处理重复错误,但是你必须自己检查索引,看看是哪个字段导致了重复

    上述方法将在您插入/更新文档时处理重复错误,因此您不需要当前的验证代码。

    为了改善你的验证流程,如果你想避免嵌套的 Promise,你可以使用Promise.all()同时调用它们

    /* without async/await */
    
    Promise.all([
      User.findOne({ email: req.body.email }).exec(),
      User.findOne({ phoneNo: req.body.phoneNo }).exec()
    ]).then(([emailUser, phoneUser]) => {
      if (emailUser) {
        errors.email = "Email already exists";
        return res.status(400).json(errors);
      }
    
      if (phoneUser) {
        errors.phoneNo = "Phone no already exists";
        return res.status(400).json(errors);
      }
    })
    
    
    /* with async/await */
    
    const [emailUser, phoneUser] await Promise.all([
      User.findOne({ email: req.body.email }).exec(),
      User.findOne({ phoneNo: req.body.phoneNo }).exec()
    ])
    if (emailUser) {
      errors.email = "Email already exists";
      return res.status(400).json(errors);
    }
    
    if (phoneUser) {
      errors.phoneNo = "Phone no already exists";
      return res.status(400).json(errors);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-22
      • 1970-01-01
      • 1970-01-01
      • 2013-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-19
      相关资源
      最近更新 更多