2017-09-28 6 views
2

그냥 nodejs/mongoose를 사용하기 시작했는데 고전적인 비동기 문제가 있다고 생각합니다. 누군가이 비동기 문제를 해결하는 방법을 안내해 줄 수 있습니까?비동기 라이브러리가있는 회 돌이에서 몽구스 비동기 호출

이 함수는 "getAreasRoot"이며 내부에는 다른 비동기 함수의 결과를 채우는 루프가 있습니다. 비동기 라이브러리로 어떻게 해결할 수 있습니까?

areaSchema.statics.getAreasRoot = function(cb: any) { 
    let self = this; 
    return self.model("Area").find({ parentId: null }, function(err: any, docs: any){ 
     docs.forEach(function(doc: any){ 
      doc.name = "Hi " + doc.name; 
      doc.children = self.model("Area").getAreasChildren(doc._id, function(err: any, docs: any){}); 
     }) 
     cb(err, docs); 
    }); 
}; 

areaSchema.statics.getAreasChildren = function(id: any, cb: any) { 
    return this.model("Area").find({ parentId: null }).exec(cb); 
} 
+1

[for 루프 내부에서 몽구스 기능을 어떻게 사용할 수 있습니까?] (https://stackoverflow.com/questions/44569770/how-can-i-use-mongoose-functions-inside-a-for- 루프) –

+0

@KevinB OP가 async.js와 함께 사용하는 방법을 묻는다면 실제로는 중복되지 않습니다. 제공된 답변 중 어느 것도 async.js를 사용하지 않습니다. – Mikey

답변

0

두 가지 작업이 있습니다. 뿌리를 얻은 다음 뿌리를 사용하여 자식을 가져옵니다.

async.js를 사용하여이 작업을 수행하려면 async.waterfallasync.mapSeries의 조합을 사용합니다. .waterfall은 첫 번째 작업의 결과를 두 번째 작업으로 전달하기 때문에 사용합니다. .mapSeries을 사용합니다. 각 루트 영역을 이름과 자식으로 변경하려고하기 때문입니다.

areaSchema.statics.getAreasRoot = function (cb) { 
    let self = this; 
    async.waterfall([ 
     // every task has a callback that must be fired at least/most once 
     // to tell that the task has finished OR when an error has occurred 
     function getRoots (cb1) { 
      self.find({ parentId: null }, cb1); 
     }, 
     function getChildren (roots, cb2) { 
      async.mapSeries(roots, function (root, cb3) { 
       // inside this block, we want to fire the innest callback cb3 when 
       // each iteration is done OR when an error occurs to stop .mapSeries 
       self.find({ parentId: root._id }, function (err, children) { 
        // error: stop .mapSeries 
        if (err) 
         return cb3(err); 
        root.name = "Hi " + root.name; 
        root.children = children; 
        // done: send back the altered document 
        cb3(null, root); 
       }); 
      // the last argument is fired when .mapSeries has finished its iterations 
      // OR when an error has occurred; we simply pass the inner callback cb2 
      }, cb2) 
     } 
    // the last argument is fired when .waterfall has finished its tasks 
    // OR when an error has occurred; we simply pass the original callback cb 
    ], cb); 
}; 

는 실제에 반대 약속을 반환하는 그것을 제외하고

몽구스 작업이 비동기

Area.getAreasRoot(function (err, areas) { 
    console.log(err, areas); 
}) 

, 그래서

doc.children = self.model("Area").getAreasChildren(...) 

가 올바르지 않은 사용 서류.

또한

당신 virtual population 또는 aggregation와 논리를 단순화 할 수 있습니다.

+0

대단히 고마워요. 완벽한 문서화 된 답변 – Michalis

+0

자녀들을 또한 쉽게 얻을 수있는 방법이 있습니까? – Michalis

+0

@Michalis 당신이 이것을 묻기 시작했다는 느낌이 들었습니다. 불행히도, 나는 async.js로하는 것이 좋은 생각인지 모른다. 스키마를 다시 생각해 볼 수도 있습니다. [This] (https://docs.mongodb.com/v3.2/tutorial/model-tree-structures/)가 도움이 될 수 있습니다. – Mikey