将数组拆分为块/块,并对其进行一对一的操作

时间:2019-03-15 17:48:19

标签: javascript arrays asynchronous optimization rxjs

我对标签有点抱歉,可能是我理解我的问题不对,并错误地使用了它们。.

我的项目面临的问题对我来说是新的,我从未经历过。因此,就我而言,我从数据库(Mongo,100'000多个文档)获得了巨大的数据集响应,我需要http-request从文档中获取每个特定字段。

数据集中的示例数组如下:

{
    _id: 1,
    http: http.request.me
},
{
    //each doc of 99k docs more
}

所以您可能已经知道我不能使用默认的for loop,因为

  1. 如果它async,我会被要求大量请求API,并且会 被禁止/限制/任何内容
  2. 如果我做到了one-by-one,则大约需要12-23H 等待我的循环完成。 (实际上,这种方式在 使用)
  

这就是我现在想要做的

  1. 还有另一种方式,这就是为什么我在这里。我可以将巨大的数组拆分为多个块,例如每个5/10 / 100..N并请求它们one-by-one

    │→await[request_map 0,1,2,3,4]→filled
    │→await[request_map 5..10]→filled
    │→await[request_map n..n+5]→filled
    ↓
    

根据Split array into chunks,我可以轻松地做到这一点。但是然后我应该使用2个for周期,第一个将拆分默认数组,第二个async-request拆分这个新数组(长度5/10/100 ... N)

但是我最近听说过反应式和RxJS(可能)可以解决这个问题。这是正确的吗?我应该使用什么运算符?我应该使用什么关键字来发现相关问题? (如果我用反应式编程进行搜索,我将收到很多与react.js无关的结果,但不是我想要的)

因此,我应该关心所有这些,而只是编写未优化的代码,还是为此问题或另一种更好的模式/解决方案提供一个npm-module

  

可能我在这里找到并回答   RxJS 1 array item into sequence of single items - operator我正在检查,但也要感谢任何相关的贡献   这个问题


  

在这种情况下,RxJS确实很有帮助,值得一看。这是一个   解决这类问题的好方法

2 个答案:

答案 0 :(得分:2)

利用bufferCount和concatMap

range(0,100).pipe(
    // save each http call into array as observable but not executing them
    map(res=>http(...)),
    //5 at a time
    bufferCount(5),
    //execute calls concurrently and in a queue of 5 calls each time
    concatMap(res=>forkJoin(res))
).subscribe(console.log)

答案 1 :(得分:1)

实际上,使用mergeMap运算符可以更轻松地完成所需操作,它是第二个可选参数,用于设置并发内部Observable的数量:

from([obj1, obj2, obj3, ...]).pipe(
  mergeMap(obj => /* make a request out of `obj` */, 5), // keep only 5 concurrent requests
).subscribe(result => ...)