Zone.run în Dart

fork creează o zonă copil cu valori sau reguli proprii; run execută o funcție în interiorul unei zone.

Sintaxă
R run<R>(R action())
Zone fork({ZoneSpecification? specification, Map<Object?, Object?>? zoneValues})

Ce face Zone.run

zona.fork(...) creează o zonă nouă, copil al zonei pe care o chemi. Cu zoneValues îi atașezi valori, iar cu ZoneSpecification poți intercepta operații: print, erorile netratate, crearea de timere.

zona.run(f) cheamă f în acea zonă și returnează rezultatul. Tot codul asincron pornit din f rămâne în zonă. runZoned este o prescurtare pentru Zone.current.fork(...).run(...).

Parametri

Parametru Descriere
action Pentru run: funcția executată în zonă.
specification Pentru fork: operațiile interceptate.
zoneValues Pentru fork: valorile atașate zonei.

Ce returnează

run returnează rezultatul funcției; fork returnează zona nouă.

Exemple

Exemplul 1: Interceptarea lui print

Zona adaugă un prefix fiecărui print din codul rulat în ea, inclusiv din timere.

import 'dart:async';

Future<void> main() async {
  final zonaTest = Zone.current.fork(
    specification: ZoneSpecification(
      print: (self, parent, zone, linie) => parent.print(zone, '[TEST] $linie'),
    ),
  );
  final gata = Completer<void>();
  zonaTest.run(() {
    print('pornesc testul');
    Timer(const Duration(milliseconds: 10), () {
      print('verificare din timer');
      gata.complete();
    });
  });
  await gata.future;
  print('în afara zonei');
}

Rezultat

[TEST] pornesc testul
[TEST] verificare din timer
în afara zonei

Exemplul 2: fork cu valori și run cu rezultat

import 'dart:async';

String salut() => '${Zone.current[#limba] == 'en' ? 'Hello' : 'Bună ziua'}, ${Zone.current[#nume]}!';

void main() {
  final ro = Zone.current.fork(zoneValues: {#limba: 'ro', #nume: 'Ana'});
  final en = ro.fork(zoneValues: {#limba: 'en'});
  print(ro.run(salut));
  print(en.run(salut));
}

Rezultat

Bună ziua, Ana!
Hello, Ana!

Greșeli frecvente

  • În funcția print a specificației chemi print obișnuit. Ajungi din nou în aceeași funcție, la nesfârșit; folosește parent.print(zone, ...).

Comenzi înrudite

  • Zone: Contextul în care rulează codul asincron; Zone.current este zona de acum, din care poți citi valori atașate.
  • runZonedGuarded: Rulează cod într-o zonă nouă și prinde toate erorile asincrone netratate din ea, cu o singură funcție.