在使用 node.js 完成所有承诺后,我想在 mongodb 中插入数据
Posted
技术标签:
【中文标题】在使用 node.js 完成所有承诺后,我想在 mongodb 中插入数据【英文标题】:i want to insert data in mongodb after all promises have been done by using node.js 【发布时间】: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 的新手。提前致谢。
【问题讨论】:
【参考方案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);
)
【讨论】:
以上是关于在使用 node.js 完成所有承诺后,我想在 mongodb 中插入数据的主要内容,如果未能解决你的问题,请参考以下文章