我正在使用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();
});
});
});
}
}
答案 0 :(得分:5)
另外,我已经编写了一个小模块,可以为你处理加载灯具,所以你只需这样做:
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
它还将加载夹具文件或对象的目录。
答案 1 :(得分:2)
答案 2 :(得分:2)
我最近创建了一个名为 wait.for 的简单抽象来在同步模式下调用异步函数(基于Fibers)。它处于早期阶段但有效。它在:
https://github.com/luciotato/waitfor
使用 wait.for ,您可以调用任何标准nodejs async函数,就好像它是同步函数一样,没有阻塞节点的事件循环。您可以在需要时按顺序编码。
使用 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();
}
答案 3 :(得分: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();
});
});
答案 4 :(得分:0)
如果您已在项目中的任何位置使用underscore.js
,则可以使用after
方法。你需要提前知道有多少异步调用,但除此之外它是一个非常优雅的解决方案。