Stream.asyncMap în Dart

asyncMap transformă fiecare valoare cu o funcție asincronă, pe rând; asyncExpand înlocuiește fiecare valoare cu un stream.

Sintaxă
Stream<E> asyncMap<E>(FutureOr<E> convert(T event))
Stream<E> asyncExpand<E>(Stream<E>? convert(T event))

Ce face Stream.asyncMap

asyncMap este map pentru funcții care returnează Future. Pentru fiecare valoare cheamă funcția, așteaptă rezultatul, îl emite, și abia apoi trece la valoarea următoare. Ordinea se păstrează.

asyncExpand cheamă funcția, care returnează un stream, și emite toate valorile acelui stream înainte de a trece la valoarea următoare. Este varianta asincronă a lui expand.

Parametri

Parametru Descriere
convert Pentru asyncMap: funcția (sincronă sau asincronă) care dă valoarea nouă. Pentru asyncExpand: funcția care dă un stream.

Ce returnează

Un stream nou cu rezultatele.

Exemple

Exemplul 1: Profilul fiecărui utilizator

Future<String> profil(int id) async {
  await Future.delayed(Duration(milliseconds: 40 - id * 10));
  return 'utilizator #$id: ${['Ana', 'Mihai', 'Ioana'][id - 1]}';
}

Future<void> main() async {
  final iduri = Stream.fromIterable([1, 2, 3]);
  await for (final p in iduri.asyncMap(profil)) {
    print(p);
  }
}

Rezultat

utilizator #1: Ana
utilizator #2: Mihai
utilizator #3: Ioana

Exemplul 2: asyncExpand: paginile fiecărui capitol

Stream<String> pagini(String capitol) async* {
  for (var p = 1; p <= 2; p++) {
    await Future.delayed(const Duration(milliseconds: 5));
    yield '$capitol, pagina $p';
  }
}

Future<void> main() async {
  final capitole = Stream.fromIterable(['Capitolul 1', 'Capitolul 2']);
  await capitole.asyncExpand(pagini).forEach(print);
}

Rezultat

Capitolul 1, pagina 1
Capitolul 1, pagina 2
Capitolul 2, pagina 1
Capitolul 2, pagina 2

Greșeli frecvente

  • Te aștepți ca asyncMap să ruleze cererile în paralel. Le rulează pe rând; pentru paralelism, adună future-urile și folosește Future.wait.

Comenzi înrudite

  • Stream.map: Creează un stream nou în care fiecare valoare este transformată cu o funcție sincronă.
  • Stream.expand: Înlocuiește fiecare valoare a stream-ului cu zero, una sau mai multe valori dintr-un Iterable.
  • Future.wait: Future.wait așteaptă mai multe future-uri în paralel și dă lista rezultatelor; Future.any dă primul rezultat terminat.
  • async*: O funcție async* produce un Stream: trimite valori cu yield, în timp, și poate folosi await între ele.