【问题标题】:How to get rid of the asynchoronous code here如何摆脱这里的异步代码
【发布时间】:2012-10-08 13:19:09
【问题描述】:

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

     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>'); 
   });

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

【问题讨论】:

  • 您是否尝试过在 db.frames.find 的回调中移动 res.end 调用?
  • 是的,我在这里尝试了所有组合。但没有成功。纽约市下面​​提供的答案有效,感谢您的努力。

标签: node.js mongodb asynchronous


【解决方案1】:

不要对抗 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>);
      }
    });


  } 
}) 

【讨论】:

  • 很高兴知道。祝你有美好的一天:)
  • 好吧,如果没有您的数据和服务器,就很难判断。我说,是时候进行小调试了。
  • 是的,谢谢你的帮助。我现在对你的逻辑进行了一些研究。真的应该赞美你的脑力劳动。
【解决方案2】:

只需将res.end('&lt;/body&gt;&lt;/html&gt;'); 放在您的db.frames.find 函数中。检查您何时到达doc.length - 1,然后发送end 命令。

【讨论】:

  • 我知道 node.js 中的请求是完全异步的。如果是这样,那么检查 doc.length 是不可靠的,因为某些响应可能仍在进行中。
猜你喜欢
  • 2020-03-25
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 2012-02-05
  • 2018-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多