仅在完成两个MongoDB数据库查询时呈现页面

时间:2011-12-06 19:59:13

标签: javascript mongodb node.js asynchronous

我试图渲染一个'项目'从数据库中检索。有两种类型的项目涉及用户,他们拥有的项目以及他们所属的项目。

我使用了两个异步数据库查询,但是它们可以在不同的时间完成,我只想在它们完成时呈现页面。

问题: 如何在数据库事务完成之前延迟渲染?

  var username = req.session.username;
  var memberProjects = [];
  var ownerProjects = [];
  var membersQuery = false;
  var ownerQuery = false;

  projects.find({"members.username" : username}).toArray(function(err, results)
  {
    for(var i = 0; i < results.length; i++)
    {
      var project = {
        title : results[i].title,
        id : results[i]._id
      }
      memberProjects[i] = project;
    }
    membersQuery = true;
  });

  projects.find({owner : req.session.username}).toArray(function(err, results)
  {
    for(var i = 0; i < results.length; i++)
    {
      var project = {
        title : results[i].title,
        id : results[i]._id
      }
      ownerProjects[i] = project;
    }
    ownerQuery = true;
  });

  if( membersQuery && ownerQuery )
  {        
    res.render('project', {
      ownerProjects : ownerProjects,
      memberProjects : memberProjects
    });        
  }

2 个答案:

答案 0 :(得分:0)

我有一个合适的答案,我不确定它是否正确。如果有更好的方法,请纠正我。我在每个数据库事务结束时调用一个函数:

  var username = req.session.username;
  var memberProjects = [];
  var ownerProjects = [];
  var membersQuery = false;
  var ownerQuery = false;

  projects.find({"members.username" : username}).toArray(function(err, results)
  {
    for(var i = 0; i < results.length; i++)
    {
      var project = {
        title : results[i].title,
        id : results[i]._id
      }
      memberProjects[i] = project;
    }
    membersQuery = true;
    render();
  });

  projects.find({owner : req.session.username}).toArray(function(err, results)
  {
    for(var i = 0; i < results.length; i++)
    {
      var project = {
        title : results[i].title,
        id : results[i]._id
      }
      ownerProjects[i] = project;
    }
    ownerQuery = true;
    render();
  });

  function render(){
    if( membersQuery && ownerQuery )
    {        
      res.render('project', {
        ownerProjects : ownerProjects,
        memberProjects : memberProjects
      });        
    }
  }

答案 1 :(得分:0)

虽然您的解决方案适用于此特定示例,但您应使用某些控制流库,例如StepAsync

以下是我将如何使用Step执行此操作:

var Step = require('step'),
    username = req.session.username,
    memberProjects = [],
    ownerProjects = [],
    membersQuery = false,
    ownerQuery = false;

Step(
  function getData() {
    var that = this;
    projects.find({"members.username" : username}).toArray(function(err, results) {
      if (err) { throw new Error('database problem'); }
      for(var i = 0; i < results.length; i++) {
        var project = {
          title : results[i].title,
          id : results[i]._id
        }
        memberProjects[i] = project;
      }
      that.parallel(memberProjects);
    });
    projects.find({owner : req.session.username}).toArray(function(err, results) {
      if (err) { throw new Error('database problem'); }
      for(var i = 0; i < results.length; i++) {
        var project = {
          title : results[i].title,
          id : results[i]._id
        }
        ownerProjects[i] = project;
      }
      that.parallel(ownerProjects);
    });
  },
  function renderTemplate(memberProjects, ownerProjects) {
    res.render('project', {
      ownerProjects : ownerProjects,
      memberProjects : memberProjects
    });
  }
);