1

我正在尝试使用nano编写一个带有可重用数据库调用的小型库。

db.view('list', 'people', function(error, data) {
  if (error == null) {
    res.render('people/index', {
      people: data.rows
    });
  } else {
    // error
  }
});

当有多个请求时,这可能会变得非常混乱:

db.view('list', 'people', function(error, people) {
  db.view('list', 'items', function(error, items) {
    db.view('list', 'questions', function(error, questions) {
      db.view('list', 'answers', function(error, answers) {
        ...
        res.render('people/index', {
          people: people.rows,
          items: items.rows,
          questions: questions.rows
          ...

所以,这个想法是创建一个函数:

var getPeople = function() {
  // do db calls here and return
}

res.render('people/index', {
  people: getPeople()
});

但这不起作用。

我该如何解决这个问题并将所有内容放入外部 node-js-module.js 文件中?

4

4 回答 4

3

我建议caolan的aysnc库。非常易于使用,它可以在浏览器和沙发上使用 require (不是你将在沙发上使用来查询)。

对于特定问题,您可以使用系列或瀑布:

于 2012-02-16T18:20:29.583 回答
2

您是否考虑过在 CouchDB 中对您的视图进行视图整理?这将帮助您减少 db.view(..) 调用的数量并在 1 个视图查询中返回您需要的所有数据。单个一对多(即“人”有许多“项目”)非常容易。对于多个级别可能会付出更多的努力,但它应该以相同的方式工作。这里有一些关于 Couch view collat​​ion 的好文章:

CouchDB 加入

CouchDB 查看排序规则

于 2012-02-16T16:40:50.410 回答
2

我所知道的最好的解决方案是使用promises。这需要一点时间来适应,但值得付出努力。我正在使用Kris Kowal 的 Q-library。他在 JSConf-2010上对 Q API 和设计进行了很好的演练(跳转到 15:30)。

于 2012-02-16T17:18:56.400 回答
1

你已经在这里得到了一些很好的答案。

从 nano 源代码中,您有一个可能有帮助的示例:

此外,如果您不太了解 nodejs 流控制的工作原理,我不推荐您阅读本教程:

比使用工具更好的是使用工具了解它的工作原理:) 也许您最终只会编写自己的控制流,这就是我们大多数人最终会做的事情。

希望这会有所帮助,为方便起见附上代码。

  var db    = require('nano')('http://localhost:5984/emails')
    , async = require('async')
    ;

  function update_row(row,cb) {
    var doc = row.doc;
    delete doc.subject;
    db.insert(doc, doc._id, function (err, data) {
      if(err)  { console.log('err at ' + doc._id);  cb(err); }
      else     { console.log('updated ' + doc._id); cb(); }
    });
  }

  function list(offset) {
    var ended = false;
    offset = offset || 0;
    db.list({include_docs: true, limit: 10, skip: offset}, 
      function(err, data) {
        var total, offset, rows;
        if(err) { console.log('fuuuu: ' + err.message); rows = []; return; }
        total  = data.total_rows;
        offset = data.offset;
        rows   = data.rows;
        if(offset === total) { 
          ended = true;
          return; 
        }
        async.forEach(rows, update_row, function (err) {
          if(err) { console.log('something failed, check logs'); }
          if(ended) { return; }
          list(offset+10);
        });
    });
  }

  list();
于 2012-02-17T11:52:32.887 回答