我有一个orientdb数据库。我想使用带有RESTfull调用的nodejs来创建大量记录。我需要得到每个的@rid进行后续处理。
我的伪代码是:
for each record
write.to.db(record)
when the async of write.to.db() finishes
process based on @rid
carryon()
我已经陷入了严重的回调地狱。最接近的版本在.then函数中使用尾递归来将下一条记录写入db。但是,我无法继续进行剩余的处理。
最后一个限制是我支持公司代理,不能通过网络管理员使用任何其他软件包,因此使用本机nodejs软件包是必不可少的。
有什么建议吗?
答案 0 :(得分:2)
通过完成回调,此类问题的一般设计模式使用本地函数进行每次写入:
var records = ....; // array of records to write
var index = 0;
function writeNext(r) {
write.to.db(r, function(err) {
if (err) {
// error handling
} else {
++index;
if (index < records.length) {
writeOne(records[index]);
}
}
});
}
writeNext(records[0]);
这里的关键是你不能使用像.forEach()
那样的同步迭代器,因为它们不会一次迭代一个并等待完成。相反,你做自己的迭代。
如果您的write函数返回一个promise,您可以使用常用于迭代数组的.reduce()
模式。
var records = ...; // some array of records to write
records.reduce(function(p, r) {
return p.then(function() {
return write.to.db(r);
});
}, Promsise.resolve()).then(function() {
// all done here
}, function(err) {
// error here
});
此解决方案链在一起承诺,在执行下一次保存之前等待每个解析。
答案 1 :(得分:0)
很难说哪个函数最适合你的场景而不是更详细,但我几乎总是使用asyncjs
来做这类事情。
根据您的说法,一种方法是使用async.map
:
var recordsToCreate = [...];
function functionThatCallsTheApi(record, cb){
// do the api call, then call cb(null, rid)
}
async.map(recordsToCreate, functionThatCallsTheApi, function(err, results){
// here, err will be if anything failed in any function
// results will be an array of the rids
});
你也可以查看其他的以启用限制,这可能是一个好主意。