我在Node.js中编写一个脚本,需要执行以下操作:
我已经看了一段时间并得出结论,使用异步mongodb几乎不可能做到这一点。问题是多方面的,但是例如,如果您正在处理20,000个这样的节点,那么执行异步将挂起脚本。但是,由于步骤4需要查看对象是否已存在,因此将它们作为批量插入进行操作是不可行的。
有可能将一些可怕的东西拼凑在一起来缓存创建的对象,然后将它们保存为类似于步骤7的东西,除非它很难,因为对象进入了多个集合,你需要尝试首先从缓存中查找对象,然后在步骤4中查找数据库。如果这是解决方案,那么我将把Javascript写为已损坏并在perl中写入此内容。所以我的问题是,对于像上面的动作序列这么简单的事情,我能不能以某种方式强制 mongodb同步,以便我的脚本不会变成疯狂?我希望能够说出document.save()(顺便说一下,我使用的是Mongoose),然后让它在实际保存之后才会返回。
修改:添加了代码
这是从一个循环调用大约20000次。我不在乎(在合理范围内)需要多长时间,但是200,000异步调用保存会使脚本挂起,因此它不会那样(它在那时也使用超过1.5g的ram)。如果我不能使 hObj.save(); 等到对象实际保存,那么我将需要用更有能力的语言来编写它。
models('hs').findOne({name: r2.$.name}, function (err, h) {
if (err) {
console.log(err);
} else {
var resultObj = createResult(meeting, r1, r2);
if (h == undefined) {
var hObj = new models('hs')({
name : r2.$.name,
results : [resultObj],
numResults : 1
});
hObj.save();
} else {
h.results.push(resultObj);
h.numResults++;
h.save();
}
}
});
答案 0 :(得分:6)
来自async github页面:
eachSeries (arr,iterator,callback)
与每个项目相同,只有迭代器应用于arr in中的每个项目 系列。下一个迭代器仅在当前迭代器调用时调用 完成。这意味着迭代器函数将按顺序完成。
假设您在节点
中拥有XML节点async.eachSeries(
nodes,
// This will be applied to every node in nodes
function (node, callback) {
models('hs').findOne({name: r2.$.name}, function (err, h) {
if (err) {
console.log(err);
} else {
// Async?
var resultObj = createResult(meeting, r1, r2);
if (h == undefined) {
var hObj = new models('hs')({
name : r2.$.name,
results : [resultObj],
numResults : 1
});
hObj.save(function (err, p) {
// Callback will tell async that you are done
callback();
});
} else {
h.results.push(resultObj);
h.numResults++;
h.save(function (err, p) {
// Callback will tell async that you are done
callback();
});
}
}
});
},
// This will be executed when all nodes has been processed
function (err) {
console.log('done!');
}
);