2017-04-12 32 views
1

我试图找到价值投2模型Res.send功能Model.find()之前进行的NodeJS

.get(function(req, res) { 
     var sellerPosts = []; 
     Product.find({seller_id : req.params.seller_id}, function(err, products) { 
      if (err) throw err; 
      for (var i = 0; i < products.length; i++) { 
       console.log("id", products[i].id); 
       Post.find({product_id : products[i].id}, function(err, posts) { 
        if (err) throw err; 
        for (var j = 0; j < posts.length; j++) { 
         sellerPosts.push(posts[j]); 
         console.log("in find",sellerPosts); 

        } 
       }); 
       console.log(sellerPosts); 
      } 
      console.log("test", sellerPosts); 

      res.send(sellerPosts); 
     }); 

    }) 

这是日志的问题时:

App listening on port 3000! 
Connected to database 
id 58ea96464429aa154cb8c43a 
[] 
id 58ed3171a0cc7f20f4c74c1c 
[] 
test [] 
in find [ { _id: 58ed28b8993a2317e41fc742, 
    product_id: 58ea96464429aa154cb8c43a, 
    phone: 9123123, 
    address: 'hanhitie17', 
    other: 'no others', 
    __v: 0 } ] 
in find [ { _id: 58ed28b8993a2317e41fc742, 
    product_id: 58ea96464429aa154cb8c43a, 
    phone: 9123123, 
    address: 'hanhitie17', 
    other: 'no others', 
    __v: 0 }, 
    { _id: 58ed33cea0cc7f20f4c74c1d, 
    product_id: 58ed3171a0cc7f20f4c74c1c, 
    phone: 9123123, 
    address: 'hanhitie17', 
    other: 'no others', 
    __v: 0 } ] 

第一sellerPosts仍然打印出真正的值,但“测试”日志是空的。 做了一些日志。我认为这是因为在Product.find()中的第一个之后,程序运行res.send,然后运行Post.find()。 请帮我解决这个问题,请!!!!

+1

你应该看一看节点的'async'模块,尤其是'async.each'(http://caolan.github.io/async/) – devnull69

+0

或只是调用'res.send'当你的回调里面有'i === products.length'时。异步模块效果很好,承诺也如此,但在使用这些软件包之前,您应该知道控制流程的工作原理。 – richardpringle

回答

0

你调用一个循环Post.find其由于它是一个异步操作,因此需要使其顺序执行,因此会造成问题。您可以使用异步库来完成它,如下面的代码所示。

.get(function(req, res) { 
     var sellerPosts = []; 
     Product.find({seller_id : req.params.seller_id}, function(err, products) { 
      if (err) throw err; 
      async.eachSeries(products, function(product, next){ 
       Post.find({product_id : product.id}, function(err, posts) { 
        if (err) next(err); 
        for (var j = 0; j < posts.length; j++) { 
         sellerPosts.push(posts[j]); 
         console.log("in find",sellerPosts); 
        } 
        next(null); 
       }); 
      }, function(err){ 
       if(err) throw err; 
       res.send(sellerPosts); 
      }) 
     }); 

    }) 
0

Post.find结束是响应返回,这是正确的行为,因为JavaScript是异步的,你应该使用promises

所以我rewrited代码中使用的承诺:

.get((req, res) => { 

    Product.find({ seller_id: req.params.seller_id }) 
    .then(products => { 

    let postPromises = products.map(product => { 
     return Post.find({ product_id: product.id }); 
    }); 

    return Promise.all(postPromises); 
    }) 
    .then(posts => { 
    let sellerPosts = Array.prototype.concat.apply([], posts); 

    res.json(sellerPosts); 
    }) 
    .catch(err => { 
    throw err; 
    }); 

}); 
+0

为什么promisejs?如果我没有弄错,promisejs的意思是前端和后端。据我所知,[bluebird](http://bluebirdjs.com/)是最快的后端承诺库......但对于刚开始的人来说,NodeJS 4.x及以上版本支持原生承诺,甚至不需要第三方软件包。 – richardpringle

+0

正如你所看到的,我使用node.js的本地承诺,我将promise连接起来,因为它具有良好的文档,并且很容易理解承诺以及如何使用它 – kaxi1993

+0

我使用上面的代码,但它有“SyntaxError:Unexpected token = >“我已经安装了诺言,也是一个局部变量。如果您的nodejs版本不是最新的稳定版,请使用以下命令更新它: 'sudo npm cache clean -f', 'sudo npm install -gn', 如果您的nodejs版本不是最新版本,我确实升级了我的nodejs版本 –