concurrentPool

Como concurrent, pero emite los resultados por orden de finalización — el primero que acaba es el primero que sale.

FxAsyncIterable<A> concurrentPoolAsync<A>(int length, FxAsyncIterable<A> iterable) FxAsync<T> FxAsync.concurrentPool(int length) // chain

Lección

concurrentPool(n) mantiene hasta n peticiones en vuelo contra la fuente de aguas arriba, igual que concurrent(n) — pero te devuelve los resultados en el orden en que terminan, no en el que empezaron. Piénsalo como un pool de workers: en cuanto se libera un hueco, se lanza en él el siguiente elemento pendiente, y el primero que acaba es el primero que se emite. Esto coincide con el concurrentPool de FxTS y es la herramienta adecuada cuando no te importa qué resultado vino de qué entrada — solo quieres reaccionar a cada resultado en cuanto está listo (por ejemplo, actualizar una lista de progreso conforme aterriza cada fetch), en lugar de bloquearte con el más lento para conservar el orden.

A diferencia de concurrent, que se guía por el marcador de demanda que llega de aguas abajo, concurrentPool mantiene su pool lleno de forma ansiosa: desde el primer pull conserva hasta n peticiones en vuelo, haya los consumidores que haya esperando. Incluso un operador terminal que tira de uno en uno como .toList() o .each() obtiene todo el solapamiento — y ve los resultados en el orden en que terminan.

Demo 1 · Orden de finalización

El elemento 1 es el más lento (300ms) y el 2 el más rápido (100ms) — el resultado sale con el más rápido primero, directamente desde .toList():

Demo 2 · Contraste con concurrent

Los mismos retardos, el mismo pool de tamaño 3 — la única diferencia es en qué orden llegan los resultados:

Pruébalo tú

Ejercicio: este pool de tamaño 1 procesa los elementos de uno en uno, en el orden en que se lanzan. Súbelo a 3 para que los tres compitan a la vez y observa cómo el orden impreso pasa a ser el de finalización.

Relacionado: concurrent — variante que preserva el orden · toAsync — el modelo basado en pull en el que se apoya · puentes con Stream — aplica concurrentPool antes de toStream() · debounce — limitación de frecuencia para callbacks