首页 文章

Mongoose save()在findOne()之前返回

提问于
浏览
0

我正在使用Mongoose,Express和NodeJS实施审批系统 .

每个帖子都有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 }
});

我试图在我的函数中首先找到映射,然后在保存时更新主帖子对象 .

我需要在保存新帖子之前检索两个批准者ID .

请提出一个很好的方法来解决它 . 我目前在做:

  • 使用Save //保存新的Post对象 returns after 2nd step, i knw save in Mongoose in async but i do not want step 2 be called before this

  • 在ApprovalMapSchema上使用findOne获取批准者ID

  • 使用批准者条目更新Post对象 .

post.save(function(err,doc){if(err){} else {console.log({success:true,msg:'成功创建新帖子',内容:doc});}});

/*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

这不适合我 . 请帮忙!

2 回答

  • 1

    我很难理解你的问题 . 但听起来你想做这样的事情(你需要根据你想做的事情来修改它,但希望它能告诉你一种处理异步行为的方法):

    //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等承诺库 . 它们还有一些很好的解决方案来处理节点中的异步行为 .

  • 0

    根据@ 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 !!干杯!

相关问题