Node.js使用Mongoose

时间:2016-09-02 04:10:03

标签: node.js mongodb express mongoose callback

我是nodejs的初学者,我遇到了一些我不理解的回调行为。我使用Express路由器使用POST请求将Mongoose对象写入Mongodb。在请求的主体中,我传递了一个嵌套的json结构,其中包含两个字段 - jobDetailsexamplesjobDetails中的数据用于创建Job Mongoose对象,examples中的数据用于创建多个Example Mongoose对象。 JobExample个对象的链接是Job在其中一个字段中包含Example个对象的列表。

我尝试实现此方法的方法是以下列方式进行回调。基本上我首先将Job对象保存到mongo,然后迭代示例 - 每次创建一个Example对象并通过.job字段将其链接到作业,同时保存{{ 1}}对象到mongo。然后在回调Example对象保存功能时,我使用新的Example对象更新了Job对象,并将更新后的版本保存到mongo。

Example

这没有像我预期的那样发挥作用。具体来说,实际保存到mongo的示例数量增加了一倍,其中有几个重复,有些丢失。我知道回调是异步的,但对我来说,仍然没有解释为什么会保存两倍的例子,有些会被复制而有些会丢失。

我最终在没有使用回调的情况下正常工作。

router.post('/jobs', function (req, res, next) {
    var job = new Job(req.body.jobDetails);
    var examples = req.body.examples;

    console.log("JOB DETAILS");
    console.log(req.body.jobDetails);

    console.log("EXAMPLES");
    console.log(req.body.examples);

    //save job
    job.save(function (err, job) {
            console.log(err);
    });

     //save examples
     for(i=0; i<examples.length;i++){

        var eg = new Example({content: examples[i]});
        eg.job=job;

        eg.save(function (err, eg){

            job.examples.push(eg);

            job.save(function(err, job){
                 console.log(err);
             });
            console.log(err);
        });
    }
});

我也不确定这是否也是最佳解决方案。但我想知道为什么我的原始方法导致了意想不到的行为。

2 个答案:

答案 0 :(得分:0)

这应该有用..

router.post('/jobs', function(req, res, next) {
    var job = new Job(req.body.jobDetails);
    var examples = req.body.examples;

    console.log("JOB DETAILS");
    console.log(req.body.jobDetails);

    console.log("EXAMPLES");
    console.log(req.body.examples);

    //save job
    job.save(function(err, result) {
        if (!err) {
            //save examples
            for (i = 0; i < examples.length; i++) {

                var eg = new Example({
                    content: examples[i]
                });
                eg.job = job;

                eg.save(function(err, eg) {

                    job.examples.push(eg);

                    job.save(function(err, job) {
                        if (!err)
                            job.examples = [];

                    });
                    console.log(err);
                });
            }
        }
    });
});

答案 1 :(得分:0)

我建议您使用像async这样的库来逐步执行此类保存操作。遵循此方法以提高代码的可读性和更好的结果

var async = require('async');
router.post('/jobs', function(req, res, next) {
    var job = new Job(req.body.jobDetails);
    var examples = req.body.examples;
    var savedExamples = [];

    console.log("JOB DETAILS");
    console.log(req.body.jobDetails);

    console.log("EXAMPLES");
    console.log(req.body.examples);

    async.eachSeries(examples, function iteratee(example, callback) {
        var eg = new Example({
            content: example
        });
        eg.job = job;
        eg.save(function(err, savedEg) {
           if(!err) {
             savedExamples.push(savedEg);
           }
           callback(err)
        });
    }, function(err) {
         if(err) {
            //handle errors
         }
         job.examples = savedExamples;
         job.save(function(err,job) {
            if(err) {
               //handle errors
            }
            //success callback
         });
    });
});

使用此方法,您必须在完成所有其他操作后仅调用一次作业的保存功能。如果在任何时刻触发错误,则整个流程停止。有关异步库的更多信息,请参阅this