2013-12-18 3 views
1

Im은 공개 토론을하고 있으며, 포럼에는 많은 스레드가 있고, 스레드에는 많은 게시물이 있고 게시물에는 게시물이 많이 있습니다.JS - Express - Mongoose는 응답을 보내기 전에 모든 몽구스의 약속을 실행합니다.

의 관계는 다음과 같이 수행됩니다 :

var PostSchema = new Schema({ 
    text: String, 
    authorId: String, 
    slug: Number, 
    posts: [{ type: Schema.Types.ObjectId, ref: 'Post'}], 
    created: { type: Date, default: Date.now } 
}); 

상위 모델은 아들이 모델의 ID의 목록이 있습니다. 게시물 게시물이 있기 때문에 난 그냥 중첩 채우기를 할 수 없어, 나는 그 응답에 이것을 사용, 전체 포럼 개체를 만들 필요가

var util = require('util'), 
    mongoose = require('mongoose'), 
    Forum = mongoose.model('Forum'), 
    Thread = mongoose.model('Thread'), 
    Post = mongoose.model('Post'), 
    async = require('async'); 

exports.show = function(req, res){ 
    var forums; 

    var getThreads = function(forum) { 
    return forum.populate('threads', function(err, _forum){ 
     if(err) throw new Error(err); 
     forum.threads = _forum.threads; 
     forum.threads.forEach(getPosts); 
     return callback(err); 
    }); 
    }; 

    var getPosts = function(thread) { 
    return thread.populate('posts', function(err, _thread){ 
     if(err) throw new Error(err); 
     thread.posts = _thread.posts; 
     thread.posts.forEach(getComments); 
     return callback(err); 
    }); 
    }; 

    var getComments = function(post) { 
    return post.populate('posts', function(err, _post){ 
     if(err) throw new Error(err); 
     post.posts = _post.posts; 
     post.posts.forEach(getComments); 
     return callback(err); 
    }); 
    }; 

    async.parallel([ 
    function(callback) { 
     return Forum.find({ ownerId: req.params.owner_id }).exec(function(err, _forums) { 
     if(err) throw new Error(err); 
     forums = _forums; 
     forums.forEach(getThreads); 
     return callback(err); 
     }); 
    } 
    ], function(err){ 
     res.json(forums); 
    } 
); 

}; 

:

는이 같은 내 컨트롤러를했다.

비동기 lib를 사용하려고했지만 약속 전에 콜백 함수를 실행합니다.

전체 포럼 개체는 어떻게 만들 수 있습니까?

답변

1

비동기 방식으로 트리 구조를 올바르게 처리해야합니다. 이 방법을 시도해보십시오

(I 테스트,하지만 작동 희망하지 않은 경우)

// ... 
var Forum = mongoose.model('Forum'); 

exports.show = function(req, res){ 
    //Get the owner's forums 
    Forum.find({ ownerId: req.params.owner_id }).exec(function(err, forums) { 
    if(err) throw new Error(err); 
    if(!forums.length) return response.json(forums); //Send an empty array if no forums where found 

    //Build forums one by one 
    var forum = forums.shift(); 
    buildForum(forum, function() { 
     forum = forums.shift(); 
     if (forum) { 
     buildForum(forum, this); 
     } else { 
     //All forums were built. 
     res.json(forums); 
     }; 
    }); 
    }); 

    var buildForum = function (forum, onSuccess) { 
    forum.populate('threads', function(err, forum){ 
     if(err) throw new Error(err); 
     if(!forum.threads.length) return onSuccess(); 

     //Build threads one by one 
     var threads = forum.threads; 
     var thread = threads.shift(); 
     buildThread(thread, function() { 
     thread = threads.shift(); 
     if (thread) { 
      buildThread(thread, this); 
     } else { 
      //All threads were built. 
      onSuccess(); 
     }; 
     }); 
    }); 
    }; 

    var buildThread = function (thread, onSuccess) { 
    thread.populate('posts', function(err, thread){ 
     if(err) throw new Error(err); 
     if(!thread.posts.length) return onSuccess(); 

     //Build posts one by one 
     var posts = thread.posts; 
     var post = posts.shift(); 
     buildPost(post, function() { 
     post = posts.shift(); 
     if (post) { 
      buildPost(post, this); 
     } else { 
      //All posts were built. 
      onSuccess(); 
     }; 
     }); 
    }); 
    }; 

    var buildPost = function (post, onSuccess) { 
    post.populate('posts', function(err, post){ 
     if(err) throw new Error(err); 
     if(!post.posts.length) return onSuccess(); 

     //Build comments one by one 
     var posts = post.posts; 
     var _post = posts.shift(); 
     buildPost(_post, function() { 
     _post = posts.shift(); 
     if (_post) { 
      buildPost(_post, this); 
     } else { 
      //All comments were built. 
      onSuccess(); 
     }; 
     }); 
    }); 
    }; 
}; 
+0

답장을 보내 주셔서 감사합니다. 거의 작동합니다. 단지 응답을 얻는 방법을 모르겠습니다. res.json (포럼); 비었다. –

+0

@ user3117180 제대로 디버깅 하시겠습니까? 빈 배열을 데이터베이스 쿼리 결과로 가져 오지 않습니까? – danypype

+0

db의 배열은 괜찮지 만 배열은 배열의 모든 요소를 ​​제거하고 결국에는 응답이 없습니다. –

1

이 내 솔루션 인 @Danypype 솔루션 단지 사소한 fixs이다.

exports.show = function(req, res){ 
    //Get the owner's forums 
    Forum.find({ ownerId: req.params.owner_id }).exec(function(err, forums) { 
    if(err) throw new Error(err); 
    if(!forums.length) return response.json(forums); //Send an empty array if no forums where found 

    //Build forums one by one 
    var forum = forums.shift(); 
    var responseForums = [forum]; 

    buildForum(forum, function() { 
     forum = forums.shift(); 
     if (forum) { 
     responseForums.push(forum); 
     buildForum(forum, arguments.callee); 
     } else { 
     //All forums were built. 
     res.json(responseForums); 
     }; 
    }); 
    }); 

    var buildForum = function (forum, onSuccess) { 
    forum.populate('threads', function(err, forum){ 
     if(err) throw new Error(err); 
     if(!forum.threads.length) return onSuccess(); 
     if(forum.length == 1) return onSuccess(); 

     var thread = forum.threads.shift(); 
     var responseThreads = [thread]; 

     buildThread(thread, function() { 
     thread = forum.threads.shift(); 
     if (thread) { 
      responseThreads.push(thread) 
      buildThread(thread, arguments.callee); 
     } else { 
      //All threads were built. 
      forum.threads = responseThreads; 
      onSuccess(); 
     }; 
     }); 
    }); 
    }; 

    var buildThread = function (thread, onSuccess) { 
    thread.populate('posts', function(err, thread){ 
     if(err) throw new Error(err); 
     if(!thread.posts.length) return onSuccess(); 

     var post = thread.posts.shift(); 
     var responsePosts = [post] 

     buildPost(post, function() { 
     post = thread.posts.shift(); 
     if (post) { 
      responsePosts.push(post); 
      buildPost(post, arguments.callee); 
     } else { 
      //All posts were built. 
      thread.posts = responsePosts; 
      onSuccess(); 
     }; 
     }); 
    }); 
    }; 

    var buildPost = function (post, onSuccess) { 
    post.populate('posts', function(err, post){ 
     if(err) throw new Error(err); 
     if(!post.posts.length) return onSuccess(); 

     //Build comments one by one 
     var _post = post.posts.shift(); 
     var response_posts = [_post]; 

     buildPost(_post, function() { 
     _post = post.posts.shift(); 
     if (_post) { 
      response_posts.push(_post); 
      buildPost(_post, arguments.callee); 
     } else { 
      //All comments were built. 
      post.posts = response_posts; 
      onSuccess(); 
     }; 
     }); 
    }); 
    }; 
};