我想通过使用node.js完成所有的承诺后在mongodb中插入数据

我使用承诺推送数组中的错误,但在它推动数组中的错误之前,它检查插入数据的条件,就像我插入数据。

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中是新的。 提前致谢。

Promise.all是你的解决scheme。 它等待所有的承诺。

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

参考链接:

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

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

同步:

 var errorsArr= []; 

asynchronous:

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

同步:

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

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

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

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

我也想build议使用提供promisification的 Bluebird Promise库,这样你可以只是promisify你的mongoose模型,而不是手动地为每个操作创build承诺。

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

您可能还想结算即将到来的ES2016新增javascript,进一步简化与asynchronous/等待的承诺。 有了它,你可以摆脱完整的.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 } }); 

签出asynchronous/等待这个伟大的文章 。 虽然这需要您使用Babel或Typescript添加额外的传译步骤。 还有最近发布的微软的Node分支,带有chakra引擎(而不是V8),它已经支持asynchronous/等待。

这是一个例子

  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}); }) 

毕竟 承诺已经完成…使用Promise.all

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

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

对你的代码最快和最简单的改变 – 重构你的代码可以使它更加时尚

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