Fetch concurrente acotado

Un límite, el orden conservado, cada fallo conservado. Este es el trabajo para el que Future.wait no tiene un primitivo.

fx(ids).mapConcurrent(n, fetch) // bound + order fx(ids).mapRetry(attempts, fetch, delay: backoff) // per-element retry await fx(ids).toAsync().mapOrAccumulate((r, id) async { r.ensure(ok, () => '…'); return await fetch(id); }, concurrency: n); // every failure kept

Lección

Traer una lista conocida de ids no es un stream de eventos. Los datos están en la mano; el trabajo es I/O; la política es «como máximo n en vuelo, resultados en el orden original». Eso es mapConcurrent (o .toAsync().map(f).concurrent(n), la misma cadena escrita en tres pasos). Future.wait(ids.map(fetch)) dispara todo de golpe. Agrupar en lotes de n espera al más lento de cada grupo. Hacerlo bien a mano es un pool de workers — un cursor compartido, huecos preasignados, futures de worker. La palabra de FxDart para ese pool es concurrent(n).

Las llamadas inestables se reintentan por elemento con mapRetry, no envolviendo el terminal entero. La validación que debe reportar cada problema — no solo el primero — es mapOrAccumulate con concurrency: n. Cada elemento corre en su propio ámbito raise, así que un fallo en uno no puede filtrarse a un hermano, y los fallos salen en el orden de entrada.

La comparación con Dart del trabajo de pool de workers da el veredicto a fxdart en claridad; el pool nativo es más corto de lo que parece una vez que lo has escrito dos veces. Esta página es ese trabajo más la mitad de errores tipados, que los ejemplos de la comparación no muestran.

Demo 1 · dos en vuelo, orden conservado

Seis fetches, nunca más de dos solapados. La llamada falsa cuenta las peticiones en vuelo para que el límite se vea en la salida.

Demo 2 · cada fallo conservado, aún acotado

Los ids pares fallan. mapOrAccumulate sigue ejecutando tres a la vez, sigue devolviendo en orden, y el Left guarda cada id par — fail-slow, no fail-fast.

Relacionado: which surface — por qué esto es pull-async · concurrent · mapConcurrent · retry / mapRetry · mapOrAccumulate · búsqueda con debounce — el trabajo de tiempo · Dart vs FxDart: dos a la vez