Разбейте массив на куски / куски и выполните операции с ними по одному - PullRequest
1 голос
/ 15 марта 2019

Я немного сожалею о тегах, возможно, я понял мою проблему неправильно и использовал их неправильно, но ..

Проблема, с которой я столкнулся в моем проекте, является новой для меня, и я никогда раньше не испытывалЭто.Так что в моем случае у меня огромный ответ набора данных из БД (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-23 часов ожидания, прежде чем мой цикл завершится.(на самом деле, этот способ используется)

Это то, что я пытаюсь сделать прямо сейчас

есть и другой путь, и именно поэтому я здесь.Я мог бы разбить свой огромный массив на куски, например, каждые 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 вкуски Я мог бы легко это сделать.Но тогда я должен использовать 2 for циклов, первый разделит массив по умолчанию, а второй async-request этот новый массив (длина 5/10/100 ... N)

Но я недавно слышал о реактивномпарадигма и RxJS, которые (вероятно) могли бы решить эту проблему.Это правильно?Какой оператор мне следует использовать?Какое ключевое слово следует использовать, чтобы найти относительные проблемы?(если я гуглю реактивное программирование , я получу много бесполезного результата с response.js, но не то, что я хочу)или есть npm-module для того или иного лучшего шаблона / решения?

Возможно, я нашел и ответил здесь Элемент массива RxJS 1 на последовательность отдельных элементов - оператор Я проверяю это сейчас, но я также ценю любой соответствующий вклад в этот вопрос


RxJS действительно помог в этом деле и стоит посмотреть.Это элегантное решение для такого рода проблем

Ответы [ 2 ]

2 голосов
/ 16 марта 2019

Использовать 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 голос
/ 16 марта 2019

На самом деле есть еще более простой способ сделать то, что вы хотите, с помощью оператора mergeMap, и это второй необязательный аргумент, который устанавливает количество одновременных внутренних наблюдаемых:

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