简体   繁体   English

如何在nodejs中进行大量但未知的REST http调用?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM