La convención de nombres *Async
Cada operador perezoso y de agregación tiene un gemelo que trabaja sobre FxAsyncIterable: mismo comportamiento, con un callback apto para async.
Lección
Como Dart no tiene currificación sin tipos, FxDart no puede sobrecargar un
único map para que funcione sobre Iterable y
FxAsyncIterable en posición data-first: los tipos de los
parámetros chocarían. Por eso cada operador perezoso y de agregación se
publica en dos formas de nivel superior: la normal para
Iterable, y un gemelo *Async para
FxAsyncIterable cuyo callback devuelve
FutureOr<R> en lugar de R. Ya has visto
algunos: map/mapAsync,
filter/filterAsync,
toList/toListAsync,
reduce/reduceAsync, fold/foldAsync,
each/eachAsync, find/findAsync:
el patrón se cumple prácticamente para todas las funciones de la librería.
Las formas encadenadas no necesitan esta división. En cuanto llamas a
.toAsync() (o empiezas desde fxAsync/fxStream),
cada método posterior de esa cadena FxAsync conserva su nombre
normal — .map(...), no
.mapAsync(...) — porque el tipo del receptor ya le dice a Dart
qué sobrecarga usar. El sufijo solo existe en el nivel superior, donde las
llamadas data-first lo necesitan para desambiguar.
Demo 1 · Unos cuantos gemelos, uno al lado del otro
Las llamadas data-first siempre necesitan el sufijo Async en cuanto
trabajas con un FxAsyncIterable:
Demo 2 · Forma data-first frente a forma encadenada
La forma encadenada se lee igual que su equivalente síncrona —sin sufijos—
una vez que .toAsync() ha cambiado el tipo del receptor:
Pruébalo tú
Ejercicio: usa el gemelo data-first *Async de map
para poner en mayúsculas cada nombre de este pipeline asíncrono.
toAsync — donde empiezan los pipelines asíncronos ·
Puentes con Stream — fromStream, fxStream, toStream ·
concurrent — evaluación en paralelo ·
map — el original síncrono