简体   繁体   English

Express.js路由处理程序执行顺序

[英]Express.js Route Handler Execution Order

I am trying to query some documents from my MongoDB database, then add the documents to an array, and then send it to a rendered view. 我试图从MongoDB数据库中查询一些文档,然后将文档添加到数组中,然后将其发送到渲染视图。 However, it seems that the line that I have to render the page is getting executed before the db query is completed. 但是,似乎我必须呈现的页面的行在db查询完成之前已得到执行。 Below is the code: 下面是代码:

router.get('/blog/:username/:postid', async function(req, res, next) {
  var posts = [];

  await collPosts.find( { $and : [{ postid : parseInt(req.params.postid) }, { username : req.params.username }] }, function(err, docs) {
    docs.each(function(err, doc) {
      if (doc) {
        var renderedTitle = renderer.render(parser.parse(doc.title));
        var renderedBody = renderer.render(parser.parse(doc.body));

        var post = { postid : doc.postid, username : doc.username, created : doc.created, modified : doc.modified, title : renderedTitle, body : renderedBody };
        posts.push(post);
        console.log("0"); // EDIT
      } 
    });
    console.log("1"); // EDIT
  });

  console.log("2"); // EDIT
  res.render('index', { title : 'Post Results', Posts : posts });
});

I am very new to using Express, so if someone could help me to get the query to execute, and then the page to render, it would be greatly appreciated. 我对使用Express非常陌生,因此如果有人可以帮助我执行查询,然后呈现页面,将不胜感激。 Currently, where I log the posts array to console, the posts array is empty (as it is executing before the query is completed). 当前,我将posts数组记录到控制台的地方,posts数组为空(因为它在查询完成之前正在执行)。 Thanks 谢谢

EDIT: When using the async/await approach (and some debugging), the 2 is now being logged to console before the 1 as expected. 编辑:当使用异步/等待方法(和一些调试)时,2现在正按预期方式记录到1之前的控制台。 However, the 0 is being logged to console after 1 and 2. Could someone help me to resolve this please? 但是,0将在1和2之后登录到控制台。有人可以帮我解决这个问题吗? Thanks 谢谢

This happens because I/O operations are asynchronous operations. 发生这种情况是因为I / O操作是异步操作。 You must wait for your db response and then send it back to client. 您必须等待数据库响应,然后将其发送回客户端。 You are sending res.render outside find callback, which results in sending response to client before your db returns something. 您正在外部find回调中发送res.render ,这导致在数据库返回内容之前将响应发送到客户端。 Put your res.render inside find callback so you will be sure you will only send your response to client after db get your docs. 将您的res.render放入find回调中,这样可以确保仅在db获取文档后才将响应发送给客户端。

router.get('/blog/:username/:postid', function(req, res, next) {
  var posts = [];

  collPosts.find( { $and : [{ postid : parseInt(req.params.postid) }, { username : req.params.username }] }, function(err, docs) {
    docs.each(function(err, doc) {
      if (doc) {
        var renderedTitle = renderer.render(parser.parse(doc.title));
        var renderedBody = renderer.render(parser.parse(doc.body));

        var post = { postid : doc.postid, username : doc.username, created : doc.created, modified : doc.modified, title : renderedTitle, body : renderedBody };
        posts.push(post);
      } 
    });
    console.log(posts);
    res.render('index', { title : 'Post Results', Posts : posts });
  });
});

I have been coding a lot in express lately, and sometimes the issue when querying the database is that it returns a promise. 我最近在Express中编写了很多代码,有时查询数据库时出现的问题是它返回了Promise。 You can either provide a callback or use ES6 async/await as shown below. 您可以提供回调或使用ES6异步/等待,如下所示。 Hope this helps! 希望这可以帮助!

router.get('/blog/:username/:postid', async function(req, res, next) {
  var posts = [];

  await collPosts.find( { $and : [{ postid : parseInt(req.params.postid) }, { username : req.params.username }] }, function(err, docs) {
    docs.each(function(err, doc) {
      if (doc) {
        var renderedTitle = renderer.render(parser.parse(doc.title));
        var renderedBody = renderer.render(parser.parse(doc.body));

        var post = { postid : doc.postid, username : doc.username, created : doc.created, modified : doc.modified, title : renderedTitle, body : renderedBody };
        posts.push(post);
      } 
    });
  });

  console.log(posts);
  res.render('index', { title : 'Post Results', Posts : posts });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM