Отображение страницы только после завершения двух запросов к базе данных MongoDB - PullRequest
0 голосов
/ 06 декабря 2011

Я пытаюсь отобразить страницу «проектов», извлеченных из базы данных.Существует два типа проектов, касающихся пользователя: проекты, которыми они владеют, и проекты, членами которых они являются.

Я использую два асинхронных запроса к базе данных, однако они могут завершаться в разное время, и я только хочу, чтобы страница на них завершалась.

Вопрос: Как отложить рендеринг до завершения транзакций базы данных?

  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 голосов
/ 07 декабря 2011

Хотя ваше решение работает для этого конкретного примера, вы должны использовать некоторые библиотеки потоков управления, такие как Step или Async .

Вот как я могу сделать это с шагом:

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
    });
  }
);
0 голосов
/ 07 декабря 2011

У меня есть рабочий ответ, я не уверен, правильно ли это или нет.Пожалуйста, поправьте меня, если есть лучший подход.Я вызываю функцию в конце каждой транзакции базы данных:

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