Mongoose save() returns 在 findOne() 之前
Mongoose save() returns before findOne()
我正在使用 Mongoose、Express 和 NodeJS 实现审批系统。
每个 post 有 2 组批准。
我实现了如下模型:
Post Schema:
var PostSchema = new Schema({
UserId: { type: ObjectId, unique: true, default: null },
/..
.. Object related fields
../
Approval1: Object, //chidschema objects of approver
Approval2: Object
});
Approval Mapping Schema:
var ApprovalMapSchema = new Schema({
UserId: { type: ObjectId, unique: true, default: null },
Approver1Id: { type: ObjectId, default: null },
Approver2Id: { type: ObjectId, default: null }
});
我试图先在我的函数中找到映射,然后在保存时更新主 post 对象。
我需要在保存新的 Post 之前检索两个批准者 ID。
请提出一个好的解决方法。我目前正在做:
- 在第 2 步后使用 Save //returns 保存新的 Post 对象,我知道
以异步方式保存在 Mongoose 中,但我不希望之前调用第 2 步
这个
- 在 ApprovalMapSchema 上使用 findOne 获取批准者 ID
使用审批者条目更新 Post 对象。
post.save(函数(错误, 文档) {
如果(错误){}
别的
{
console.log({成功: 真, 味精: 'Successful created new post', 内容: 文档});
}
});
/*var actId = activation._id, distributorId, ttlId;
var approvalMap = ApprovalMap.findOne({ userId: myUserId }, function(err, appMap) {
if (err) throw err;
else{
Approver1Id = appMap.Approver1Id;
Approver2Id = appMap.Approver2Id;
}
});
// Create child objects after this and update as subdocument
这对我不起作用。请帮忙!
我很难理解你的问题。但听起来您想做这样的事情(您需要根据您想做的事情修改它,但希望它向您展示了一种处理异步行为的方法):
//This will run a query that returns a document where userId == myUserId
ApprovalMap.findOne({ userId: myUserId }, function(err, appMap) {
if (err) throw err;
//Once the query is complete function(err, appMap) will be called
//err will contain an error object if there was an error
//appMap will be the data returned by the query.
//within this block you can run another query
//for example
ApprovalMap.findOne({approved:'some variable'},function(err, secondQueryData){
if (err) throw err;
//after this query is complete function(err, secondQueryData) will be called
//once again the err argument will be an error, and the
//secondQueyrData argument will contain your return data
//here you can do something with the data
//for example, log the results
console.log(secondQueryData)
})
});
如您所见,您可以在其他查询的回调中嵌套其他查询或步骤。这将确保事物 运行 的顺序正确。你可能还想查看 npm 异步库,或者像 q 或 bluebird 这样的 promise 库。他们也有一些很好的解决方案来处理节点中的异步行为。
根据@user2263572 的建议,使用异步库。
我现在是这样实现的:
async.waterfall(
[
function(callback){
ApprovalMap.findOne({ userId: myUserId }, function(err, appMap) {
if (err) throw err;
else{
//..Create child approval elements and assign Ids from map
callback(err, Approver1Child, Approver2Child);
}
});
},
function(Approver1Child, Approver2Child, callback){
var post = new Post(req.body);
post.distApproval = Approver1Child;
post.ttlApproval = Approver2Child;
post.userId = myUserId;
callback(null, post);
}
],
function(err, post){
//creating new order
post.save(function(err, doc) {
if (err) {
}
else
{
console.log({success: true, msg: 'Successful created new post', content: doc});
}
});
}
);
非常感谢@user2263572!!干杯!
我正在使用 Mongoose、Express 和 NodeJS 实现审批系统。
每个 post 有 2 组批准。
我实现了如下模型:
Post Schema:
var PostSchema = new Schema({
UserId: { type: ObjectId, unique: true, default: null },
/..
.. Object related fields
../
Approval1: Object, //chidschema objects of approver
Approval2: Object
});
Approval Mapping Schema:
var ApprovalMapSchema = new Schema({
UserId: { type: ObjectId, unique: true, default: null },
Approver1Id: { type: ObjectId, default: null },
Approver2Id: { type: ObjectId, default: null }
});
我试图先在我的函数中找到映射,然后在保存时更新主 post 对象。
我需要在保存新的 Post 之前检索两个批准者 ID。
请提出一个好的解决方法。我目前正在做:
- 在第 2 步后使用 Save //returns 保存新的 Post 对象,我知道 以异步方式保存在 Mongoose 中,但我不希望之前调用第 2 步 这个
- 在 ApprovalMapSchema 上使用 findOne 获取批准者 ID
使用审批者条目更新 Post 对象。
post.save(函数(错误, 文档) { 如果(错误){} 别的 { console.log({成功: 真, 味精: 'Successful created new post', 内容: 文档}); } });
/*var actId = activation._id, distributorId, ttlId; var approvalMap = ApprovalMap.findOne({ userId: myUserId }, function(err, appMap) { if (err) throw err; else{ Approver1Id = appMap.Approver1Id; Approver2Id = appMap.Approver2Id; } }); // Create child objects after this and update as subdocument
这对我不起作用。请帮忙!
我很难理解你的问题。但听起来您想做这样的事情(您需要根据您想做的事情修改它,但希望它向您展示了一种处理异步行为的方法):
//This will run a query that returns a document where userId == myUserId
ApprovalMap.findOne({ userId: myUserId }, function(err, appMap) {
if (err) throw err;
//Once the query is complete function(err, appMap) will be called
//err will contain an error object if there was an error
//appMap will be the data returned by the query.
//within this block you can run another query
//for example
ApprovalMap.findOne({approved:'some variable'},function(err, secondQueryData){
if (err) throw err;
//after this query is complete function(err, secondQueryData) will be called
//once again the err argument will be an error, and the
//secondQueyrData argument will contain your return data
//here you can do something with the data
//for example, log the results
console.log(secondQueryData)
})
});
如您所见,您可以在其他查询的回调中嵌套其他查询或步骤。这将确保事物 运行 的顺序正确。你可能还想查看 npm 异步库,或者像 q 或 bluebird 这样的 promise 库。他们也有一些很好的解决方案来处理节点中的异步行为。
根据@user2263572 的建议,使用异步库。
我现在是这样实现的:
async.waterfall(
[
function(callback){
ApprovalMap.findOne({ userId: myUserId }, function(err, appMap) {
if (err) throw err;
else{
//..Create child approval elements and assign Ids from map
callback(err, Approver1Child, Approver2Child);
}
});
},
function(Approver1Child, Approver2Child, callback){
var post = new Post(req.body);
post.distApproval = Approver1Child;
post.ttlApproval = Approver2Child;
post.userId = myUserId;
callback(null, post);
}
],
function(err, post){
//creating new order
post.save(function(err, doc) {
if (err) {
}
else
{
console.log({success: true, msg: 'Successful created new post', content: doc});
}
});
}
);
非常感谢@user2263572!!干杯!