我试图重构我的猫鼬操作,但不起作用

时间:2015-11-14 10:09:40

标签: node.js mongodb mongoose

我正在尝试重构我的猫鼬代码,因为它看起来很重复

这是代码

   var updateResume = function(query, id, set, value) {
    User.update({query: id}, {'$set': {
        set: value,
    }}, function(err, found) {
        // Do nothing
    });
}


 app.get('/testing', function(req, res) {
    updateResume('resume.educations._id', req.body.education_id,
            'resume.educations.$.school', req.body.education_school);

 });

当我没有把它放在一个函数中时,它可以正常工作。

Mongoose / Mongodb专家可以告诉我发生了什么吗?

2 个答案:

答案 0 :(得分:2)

如果要在JavaScript中使用变量作为键的名称,则需要使用括号[]表示法对其进行分配。否则,左侧的值(键)将被视为文字:

var updateResume = function(query, id, set, value,callback) {
    var Query = { },
        update = { "$set": {} };

    Query[query] = id;
    update.$set[set] = value;        

    User.update(Query, update, callback);
};

app.get('/testing', function(req, res) {
    updateResume(
        'resume.educations._id', req.body.education_id,
        'resume.educations.$.school', req.body.education_school,
        function(err,result) {
            // do something in here
        }
    );
});

此外,由于操作是异步的,因此您应该将处理回调传递给泛型方法,而不是尝试自己处理。这种方式更加灵活。

答案 1 :(得分:-2)

我在你的代码中看到两个问题:

1)您正在尝试使用参数set的值来动态设置您想要更改的属性名称。它不会这样工作。

有多种方法可以做你想要的。例如,在JavaScript 6中,您可以将此部分更改为:

User.update({query: id}, {'$set': {
    [set]: value,
}}, function(err, found) {
    // Do nothing
});

以上代码无效,除非您正在运行带有--harmony标志的节点,或者您正在使用babel进行转换(例如,我认为可能不是您的情况)。

为了便于重现,我建议使用此版本:

var changes = {};
changes[set] = value;
User.update({query: id}, {'$set': changes}, function(err, found) {
    // We will take care of it soon
});

第二个问题是关于node.js的异步性质。你不能只在你的回调中“无所事事”。工作似乎,但是有一天你的代码开始会变得奇怪,你永远不会发现问题。

当您忽略回调时,即使此操作尚未完成,您的下一行代码仍将继续运行。

这意味着如果下一行尝试读取此记录,则可能尚未更改(可能是“是”),并且您的代码有时会“有效”,有时则不会。

我更喜欢这种方式,使用承诺:

function updateResume(query, id, set, value) {
    var changes = {};
    changes[set] = value;

    return User.update({query: id}, {'$set': changes});
}

app.get('/testing', function(req, res) {
   updateResume(
       'resume.educations._id',
       req.body.education_id,
       'resume.educations._id',
       req.body.education_id
   ).then( function() {
       res.send("OK"); 
   }).catch( function (err) {
       res.send("NOK");
   })
});