2016-09-02 2 views
-1

저는 nodej 초보자입니다. 이해할 수없는 콜백 동작이 발생했습니다. 나는 익스프레스 라우터를 사용하여 Mongoose 객체를 POST 요청을 사용하여 Mongodb에 작성하고있다. 요청의 본문에서 나는 두 개의 필드, 즉 jobDetailsexamples이있는 중첩 json 구조를 전달합니다. jobDetails의 데이터는 Job 몽구스 개체를 만드는 데 사용되며 examples의 데이터는 여러 Example 몽구스 개체를 만드는 데 사용됩니다. JobExample 개체는 Job에 해당 필드 중 하나에 Example 개체 목록이 포함되어 있습니다.Node.js 몽구스로 예기치 않은 동작이 발생했습니다.

이 방법을 구현하는 방법은 다음과 같은 방법으로 콜백을 사용하는 것입니다. 기본적으로 문맥에 Job 개체를 저장 한 다음 예제를 반복합니다. 매번 Example 개체를 만들고이 개체를 .job 필드를 통해 작업에 연결하고 Example 개체를 mongo에 저장합니다. 그런 다음 Example 개체 저장 함수에 대한 콜백에서 Job 개체를 새 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); 
     }); 
    } 
}); 

예상대로 작동하지 않았습니다. 구체적으로 말하자면 몇 배의 예제와 누락 된 예제가 실제로 몽고에 저장되었습니다. 콜백은 비동기 적이지만 나에게도 여전히 예제의 수가 두 배로 저장되고 일부는 복제되고 일부는 누락 될 것이라고 설명하지 않는다는 것을 이해합니다.

결국 다음과 같은 방법으로 콜백을 사용하지 않고 올바르게 작동하게되었습니다.

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){ 
      console.log(err); 
     }); 

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

그리고 이것이 최적의 솔루션인지 잘 모르겠습니다. 하지만 원래의 접근 방식이 의도하지 않은 동작을 초래 한 이유를 알고 싶습니다.

답변

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); 
       }); 
      } 
     } 
    }); 
}); 
+0

당신은'job.save에 대한 확신 (기능 (ERR, 작업) { 경우 (ERR) job.examples의 = [];! });'부분? 모든 예제를 그냥 지우지 않습니까? – user1893354

+0

효과가 있었습니까? 이 행은 모든 예제를 저장 한 후 제거 했으므로 중복을 추가하지 않습니다. – abdulbarik

+0

하지만 모든 예제는 job.examples에 저장해야합니다. 각 job.save 다음에 예제를 지우면 이전에 저장 한 모든 것을 덮어 쓰지 않을까요? – user1893354

0

난 당신이 단계적으로 작업 저장 등을 수행하는 비동기 같은 라이브러리를 사용하는 것이 좋습니다 것입니다. 다른 모든 작업을 완료 한 후에는 한 번만 작업의 저장 함수를 호출해야합니다이 방법을 사용하면 코드의 가독성 및 더 나은 결과

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을 참조하십시오!

관련 문제