2

我将 Mongoose 与 Node.js 一起使用,并且有以下代码将在所有 save() 调用完成后调用回调。但是,我觉得这是一种非常肮脏的方式,并且希望看到完成这项工作的正确方法。

function setup(callback) {

  // Clear the DB and load fixtures
  Account.remove({}, addFixtureData);

  function addFixtureData() {
    // Load the fixtures
    fs.readFile('./fixtures/account.json', 'utf8', function(err, data) {
      if (err) { throw err; }
      var jsonData = JSON.parse(data);
        var count = 0;
        jsonData.forEach(function(json) {
          count++;
          var account = new Account(json);
          account.save(function(err) {
            if (err) { throw err; }
            if (--count == 0 && callback) callback();
          });
        });
    });
  }
}
4

5 回答 5

5

您可以使用asyncStep之类的库稍微清理一下代码。

另外,我编写了一个小模块来为您处理加载装置,所以您只需:

var fixtures = require('./mongoose-fixtures');

fixtures.load('./fixtures/account.json', function(err) {
  //Fixtures loaded, you're ready to go
};

Github: https ://github.com/powmedia/mongoose-fixtures

它还将加载夹具文件或对象的目录。

于 2011-07-13T09:36:14.917 回答
2

我讨论了常见的异步模式(串行和并行)以及解决它们的方法:

https://github.com/masylum/i-love-async

我希望它有用。

于 2011-07-13T16:10:14.273 回答
2

我最近创建了一个更简单的抽象,称为wait.for以在同步模式下调用异步函数(基于 Fibers)。它处于早期阶段,但有效。它是在:

https://github.com/luciotato/waitfor

使用wait.for,您可以调用任何标准的 nodejs 异步函数,就好像它是一个同步函数一样,而不会阻塞节点的事件循环。您可以在需要时按顺序编码。

使用wait.for您的代码将是:

//in a fiber
function setup(callback) {

  // Clear the DB and load fixtures
  wait.for(Account.remove,{});

  // Load the fixtures
  var data = wait.for(fs.readFile,'./fixtures/account.json', 'utf8');

  var jsonData = JSON.parse(data);
  jsonData.forEach(function(json) {
    var account = new Account(json);
    wait.forMethod(account,'save');
  }
  callback();
}
于 2013-08-23T01:06:50.020 回答
0

这实际上是正确的做法,或多或少。你在那里做的是一个并行循环。如果你愿意(很多人都这样做),你可以将它抽象成它自己的“异步并行 foreach”函数,但这确实是进行并行循环的唯一方法。

根据您的意图,可以以不同方式完成的一件事是错误处理。因为你正在抛出,如果有一个错误,那个回调将永远不会被执行(count不会被递减)。所以最好这样做:

account.save(function(err) {
  if (err) return callback(err);
  if (!--count) callback();
});

并在回调中处理错误。它在节点约定方面更好。

我还将更改另一件事,以省去count每次迭代递增的麻烦:

var jsonData = JSON.parse(data)
  , count = jsonData.length;

jsonData.forEach(function(json) {
  var account = new Account(json);
  account.save(function(err) {
    if (err) return callback(err);
    if (!--count) callback();
  });
});
于 2011-07-13T06:42:19.390 回答
0

如果您已经underscore.js在项目中的任何地方使用,则可以利用该after方法。您需要提前知道会有多少异步调用,但除此之外,这是一个非常优雅的解决方案。

于 2011-07-25T13:10:31.953 回答