Search code examples
dartdart-async

The purpose of function `runZoned` of 'dart:async'


There is a special function runZoned provided by dart:async. The document is here: https://api.dartlang.org/docs/channels/stable/latest/dart_async.html#runZoned

I'm not sure what's the purpose of this function, when will we need it, and how to use it properly?


Solution

  • Look at this code:

    import 'dart:async';
    
    void main() {
      fineMethod().catchError((s) {}, test : (e) => e is String);
      badMethod().catchError((s) {}, test : (e) => e is String);
    }
    
    Future fineMethod() {
      return new Future(() => throw "I am fine");
    }
    
    Future badMethod() {
      new Future(() => throw "I am bad");
      return new Future(() => throw "I am fine");
    }
    

    Output

    Unhandled exception:
    I am bad
    

    Now look at this code:

    import 'dart:async';
    
    void main() {
      fineMethod().catchError((s) {}, test : (e) => e is String);
    
      runZoned(() {
        badMethod().catchError((s) {}, test : (e) => e is String);
      }, onError : (s) {
        print("It's not so bad but good in this also not so big.");
        print("Problem still exists: $s");
      });
    }
    
    Future fineMethod() {
      return new Future(() => throw "I am fine");
    }
    
    Future badMethod() {
      new Future(() => throw "I am bad");
      return new Future(() => throw "I am fine");
    }
    

    Output

    It's not so bad but good in this also not so big.
    Problem still exists: I am bad
    

    You should strictly avoid using badMethod if this possible.

    Only if this not possible you may temporary use runZoned

    Also you may use runZoned to simulate sandboxed execution of tasks.

    Updated version of the answer:

    import 'dart:async';
    
    Future<void> main() async {
      try {
        await fineMethod();
      } catch (e) {
        log(e);
      }
    
      await runZonedGuarded(() async {
        try {
          await badMethod();
        } catch (e) {
          log(e);
        }
      }, (e, s) {
        print("========");
        print("Unhandled exception, handled by `runZonedGuarded`");
        print("$e");
        print("========");
      });
    }
    
    Future badMethod() {
      // Unhandled exceptions
      Future(() => throw "Bad method: bad1");
      Future(() => throw "Bad method: bad2");
      return Future(() => throw "Bad method: fine");
    }
    
    Future fineMethod() {
      return Future(() => throw "Fine method: fine");
    }
    
    void log(e) {
      print('Handled exception:');
      print('$e');
    }
    
    

    Output:

    Handled exception:
    Fine method: fine
    ========
    Unhandled exception, handled by `runZonedGuarded`
    Bad method: bad1
    ========
    ========
    Unhandled exception, handled by `runZonedGuarded`
    Bad method: bad2
    ========
    Handled exception:
    Bad method: fine