【问题标题】:i want to insert data in mongodb after all promises have been done by using node.js在使用 node.js 完成所有承诺后,我想在 mongodb 中插入数据
【发布时间】:2016-05-05 11:02:12
【问题描述】:

我通过使用 Promise 将错误推送到数组中,但在将错误推送到数组之前,它会检查插入数据的条件,就像我正在插入数据一样。

var errorsArr= [];

var username = new Promise(function(resolve,reject){
    User.findOne({ "username": req.body.username },function(err,user){
        if(err)
            reject(err);

        if(user) {
            resolve(1);
        }else{
            resolve(0);
        }
    });
});
username.then(function(data){
    if( data == 1 )
        errorsArr.push({"msg": "Username already been taken."});
}).catch(function(err){
    console.log(err);
});

var email = new Promise(function(resolve,reject){
    User.findOne({ "email": req.body.email },function(err,user){
        if(err)
            reject(err);

        if(user) {
            resolve(1);
        }else{
            resolve(0);
        }
    });
});
email.then(function(data){
    if( data == 1 )
        errorsArr.push({"msg": "email already been taken."});
}).catch(function(err){
    console.log(err);
});

if(errorsArr.length >0)
{
    req.session.error = errorsArr;
    return  res.redirect('/auth/Registration');
}
else {
    var newUser = new User();
    newUser.username = req.body.username;
    newUser.password = req.body.password;
    newUser.sex = req.body.sex;
    newUser.email = req.body.email;
    newUser.phoneNumber = req.body.phoneNumber;
    newUser.age = req.body.age;
    newUser.designation = req.body.designation;
    newUser.timing = req.body.timing;
    var CurrentDate = moment.tz(new Date(req.body.joiningDate), "Asia/Karachi").unix();
    newUser.joiningDate = CurrentDate;
    newUser.save(function (err, user) {
        if (!err)
            return res.redirect('/auth/Login');
    });
}

你能帮我以更好的方式做到这一点吗?我是 node.js 的新手。提前致谢。

【问题讨论】:

    标签: node.js mongodb express mongoose promise


    【解决方案1】:

    在完成所有 承诺之后...使用Promise.all

    可以编写代码底部的错误检查:

    Promise.all([username, email])
    .then(function(results) {
        if(errorsArr.length >0)
        {
            ...
        }
        else {
            ...
        }
    });
    

    对您的代码进行最快速、最简单的更改 - 重构您的代码可以使其更加流畅

    【讨论】:

      【解决方案2】:

      Promise.all 是您的解决方案。它等待所有的承诺。

       Promise.all([p1,p2,..]).then(function() {
            // all loaded
        }, function() {
         // one or more failed
       });
      

      参考链接:

      http://www.html5rocks.com/en/tutorials/es6/promises/

      【讨论】:

        【解决方案3】:

        您正在混合异步和同步代码。

        同步:

        var errorsArr= [];
        

        异步:

        var username = new Promise(...{
          ...
        });
        username.then(..
          errorsArr.push(...);
        })
        

        同步:

        if (errorsArr.length > 0) {
            ...
        

        中间的异步部分(errorsArr.push(…))实际上并没有发生在之前你的同步代码最后(if (errorsArr.length > 0))。

        如果您希望它与其他异步代码连续执行,您还需要将所有同步代码转换为异步代码。

        其他答案已经解释了如何使用Promise.all

        我还想建议使用提供promisification 的Bluebird Promise 库,这样您就可以只承诺您的猫鼬模型,而不是为每个操作手动创建承诺。

        Promise.promisifyAll(User);
        var username = User.findOneAsync(...); // the new "findOneAsync"  method returns a promise
        username.then(data => ...)
        

        您可能还想查看即将在 ES2016 中添加的 javascript 功能,这些功能进一步简化了使用 async/await 的 Promise。有了它,您可以完全摆脱.then(..),只需编写:

        app.get('/', async function(req, res) { // < async function
            try {
                var username = await User.findOneAsync(...); // await statements
                var email = await User.findOneAsync(...);
                // do stuff
            } catch(err){
                // handle errors
            }
        });
        

        Checkout this great article on async/await。尽管这需要您使用 Babel 或 Typescript 添加额外的转译步骤。还有最近发布的 Microsoft's fork of Node 附带 chakra 引擎(而不是 V8),它也已经支持 async/await。

        【讨论】:

          【解决方案4】:

          @Jaromanda X 答案是正确的,如果有用户名和电子邮件检查是独立的并且不必遵循顺序。否则,你必须做一个承诺链。

          【讨论】:

            【解决方案5】:

            这是一个例子

              Promise.all([
            Reservation.find({'parking.owner': req.payload.id}).exec(),
            Reservation.count({'parking.owner': req.payload.id}).exec(),
            Reservation.aggregate([
               { $match: {
                    _id: req.payload.id
                }},
                { $group: {
                    _id: "$_id",
                    total: { $sum: "$price"  }
                }}
                ])
              ]).then(results=>{
                 const list = results[0]
                 const count = results[1]
                 const sum = results[2]
                 res.status(200).json({list,count,sum});
              })
            

            【讨论】:

              猜你喜欢
              • 2011-08-30
              • 2021-10-20
              • 2017-12-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-03-07
              • 2022-01-25
              • 2016-08-11
              相关资源
              最近更新 更多