[英]How do I make a large but unknown number of REST http calls in nodejs?
I have an orientdb database. 我有一个orientdb数据库。 I want to use nodejs with RESTfull calls to create a large number of records. 我想使用带有RESTfull调用的nodejs来创建大量记录。 I need to get the @rid of each for some later processing. 我需要获取每个@rid以便以后进行处理。
My psuedo code is: 我的伪代码是:
for each record
write.to.db(record)
when the async of write.to.db() finishes
process based on @rid
carryon()
I have landed in serious callback hell from this. 我从此陷入了严重的回调地狱。 The version that was closest used a tail recursion in the .then function to write the next record to the db. 最接近的版本在.then函数中使用尾部递归将下一条记录写入数据库。 However, I couldn't carry on with the rest of the processing. 但是,我无法继续进行其余的处理。
A final constraint is that I am behind a corporate proxy and cannot use any other packages without going through the network administrator, so using the native nodejs packages is essential. 最后一个约束是,我位于公司代理的后面,并且必须经过网络管理员才能使用任何其他软件包,因此使用本机nodejs软件包是必不可少的。
Any suggestions? 有什么建议么?
With a completion callback, the general design pattern for this type of problem makes use of a local function for doing each write: 使用完成回调,用于此类问题的常规设计模式将利用本地函数进行每次写入:
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]);
The key here is that you can't use synchronous iterators like .forEach()
because they won't iterate one at a time and wait for completion. 这里的关键是您不能使用.forEach()
类的同步迭代器,因为它们不会一次迭代一个并等待完成。 Instead, you do your own iteration. 相反,您可以自己进行迭代。
If your write function returns a promise, you can use the .reduce()
pattern that is common for iterating an array. 如果您的写入函数返回一个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
});
This solution chains promises together, waiting for each one to resolve before executing the next save. 此解决方案链在一起的诺言,等待每个人解决,然后再执行下一个保存。
It's kinda hard to tell which function would be best for your scenario w/o more detail, but I almost always use asyncjs
for this kind of thing. 很难确定哪个函数最适合您的情况而没有更多细节,但是我几乎总是将asyncjs
用于此类情况。
From what you say, one way to do it would be with async.map
: 用您所说的话,一种方法是使用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
});
You can also check out other ones to enable throttling, which is probablya good idea. 您也可以签出其他选项以启用限制,这可能是个好主意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.