如何在这里摆脱异步代码

时间:2012-10-18 06:42:43

标签: node.js mongodb asynchronous

我一直在尝试使用MongoJS驱动程序为node.js检索数据。我使用的代码如下

     req.on('end', function(){
             var decodedBody = querystring.parse(fullBody);
             story=decodedBody.name;
             var z=new Array();
             console.log(story);
         res.writeHead(200,{'Content-Type': 'text/html'});
         res.write('<html><body>');
             db.frames.find({str_id:story}).toArray(function(err,doc){
             console.log(doc);
             for(var t=0;t<doc.length;t++)
                 {
                     var picid=doc[t].pic_id;
                     console.log(picid);               
                     db.pictures.find({_id:picid}).toArray(function(err,pic){
                      res.write('<img src="'+pic[0].name+'"/>');
             });
           } 
        }) 
        res.end('</body></html>'); 
   });

这里的问题是,由于代码的异步性,响应首先结束,然后数据库块内的代码被执行,因此浏览器上没有显示任何内容,即本例中的图像.Thankx提前。

2 个答案:

答案 0 :(得分:3)

不要与node.js的异步性质相抗衡,拥抱它!

因此,您应该发出所有请求,并在响应到达时将每个请求标记为已完成。完成所有请求后,渲染图像和body / html结束标记。

我通常不使用node.js,所以我可能会犯一些错误,但它可能看起来像这样:

res.write('<html><body>');
db.frames.find({str_id:story}).toArray(function(err,doc){
  console.log(doc);

  var completed = {};

  for(var t = 0; t < doc.length; t++) {
    var picid = doc[t].pic_id;
    completed.picid = false;
    console.log(picid);               
    db.pictures.find({_id: picid}).toArray(function(err, pic) {
      // mark request as completed
      completed.picid = pic;


      // check if all requests completed
      var all_finished = true;
      for(var k in completed) {
        if(completed[k] === false) {
          all_finished = false;
          break;
        }
      }

      // render final markup
      if(all_finished) {
        for(var k in completed) {
          var pic = completed[k];
          res.write('<img src="'+pic[0].name+'"/>');
        }
        res.end('</body></html>);
      }
    });


  } 
}) 

答案 1 :(得分:1)

只需将res.end('</body></html>');放入db.frames.find功能。检查到达doc.length - 1的时间,然后发送end命令。