Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

158
Visualizações
Using async iterator for sequential map of collection by slicing them

Let's say I have collection of events. There will be much of them, like 10-20k. For each these events I need to make additional request to get eventDetails. Base implementation would looks like:

const eventsWithDetails = await Promise.all(
  events.map(async(event) => {
    const eventDetails = await event.getEventDetails();
    return {
      ...event,
      ...eventDetails
    }
  })
);

And actually this is what I was needed with one clarification about the API I interact with: with a large number of consecutive requests, the API periodically throws errors for some of them due to overloading the endpoint. One of the brute force solution - is a just make sequential requests for bunches per N items (of course it's ugly and completely unscalable. But it works!):

const slice1 = await Promise.all(
  events.slice(0, 500).map(mapEventWithTimestamp)
);
await sleep(4000);

const slice2 = await Promise.all(
  events.slice(500, 1000).map(mapEventWithTimestamp)
);
await sleep(4000);

...slices3,
...sliceN

return [...slice1, ...slice2, ...sliceN]

As part of the search for a robust solution, I'm trying to wrap my head around implementation with usage of async iterator. Having stateful object which will also has async iteration interface. The point here to make delay of N seconds after each 1000 requests. Something like that:

let mapper = {
    start: 0,
    stop: events.length,
    step: 1000,
    result: [],


    async * [Symbol.asyncIterator]() {
      for (let current = this.start; current <= this.stop; current += this.step) {
        await sleep(4000);
        let slice = await Promise.all(events.slice(current, current + this.step);

          this.result = [...this.result, ...slice];

          yield slice;
        }
      }

      // is there way to return this.result to external usage??
    };
}

Is there any way to accomplish this task with elegant and scalable solution with async iteration? To have definitive interface like that: const eventsWithDetails = await mapEventsWithDetails(events); (which will make internal iteration and then returns mapped data)

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

You can try the following, using iter-ops library, to process everything sequentially, as an iterable:

import {pipe, toAsync, map, wait} from 'iter-ops';

const i = pipe(
    toAsync(events), // make the list asynchronous
    map(event => event.getEventDetails()), // remap into requests
    wait() // resolve each promise inside iterable
);

// this is where it will start execution;

for await(const a of i) {
    console.log(a); // print whatever data you're getting
}

And you can add delay or throttle operators to the pipeline, as needed.

And if you actually want to process data in bulk, you can make use of the page operator, to split requests into pages:

import {pipe, toAsync, map, page, wait} from 'iter-ops';

const i = pipe(
    toAsync(events),
    page(500), // split into pages of 500 items in each
    map(page => Promise.all(page.map(a => a.getEventDetails()))),
    wait() // resolve each page
);

// this will trigger processing one page at a time;
for await(const page of i) {
    console.log(page); // print a whole page of data
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda