Zone class
A better zone API which implements onTurnDone.
class Zone { Zone() { _zone = async.Zone.current.fork(specification: new async.ZoneSpecification( run: _onRun, runUnary: _onRunUnary, scheduleMicrotask: _onScheduleMicrotask, handleUncaughtError: _uncaughtError )); } async.Zone _zone; List _asyncQueue = []; bool _errorThrownFromOnRun = false; _onRunBase(async.Zone self, async.ZoneDelegate delegate, async.Zone zone, fn()) { _runningInTurn++; try { return fn(); } catch (e, s) { onError(e, s, _longStacktrace); _errorThrownFromOnRun = true; rethrow; } finally { _runningInTurn--; if (_runningInTurn == 0) _finishTurn(zone, delegate); } } // Called from the parent zone. _onRun(async.Zone self, async.ZoneDelegate delegate, async.Zone zone, fn()) { return _onRunBase(self, delegate, zone, () => delegate.run(zone, fn)); } _onRunUnary(async.Zone self, async.ZoneDelegate delegate, async.Zone zone, fn(args), args) { return _onRunBase(self, delegate, zone, () => delegate.runUnary(zone, fn, args)); } _onScheduleMicrotask(async.Zone self, async.ZoneDelegate delegate, async.Zone zone, fn()) { _asyncQueue.add(() => delegate.run(zone, fn)); if (_runningInTurn == 0 && !_inFinishTurn) { _finishTurn(zone, delegate); } } _uncaughtError(async.Zone self, async.ZoneDelegate delegate, async.Zone zone, e) { if (!_errorThrownFromOnRun) { onError(e, async.getAttachedStackTrace(e), _longStacktrace); } _errorThrownFromOnRun = false; } var _inFinishTurn = false; _finishTurn(zone, delegate) { if (_inFinishTurn) { return; } _inFinishTurn = true; try { // Two loops here: the inner one runs all queued microtasks, // the outer runs onTurnDone (e.g. scope.$digest) and then // any microtasks which may have been queued from onTurnDone. do { while (!_asyncQueue.isEmpty) { delegate.run(zone, _asyncQueue.removeAt(0)); } delegate.run(zone, onTurnDone); } while (!_asyncQueue.isEmpty); } catch (e, s) { onError(e, s, _longStacktrace); _errorThrownFromOnRun = true; rethrow; } finally { _inFinishTurn = false; } } int _runningInTurn = 0; /** * A function called with any errors from the zone. */ var onError = (e, s, ls) => null; /** * A function that is called at the end of each VM turn in which the * in-zone code or any runAsync callbacks were run. */ var onTurnDone = () => null; // Type was ZoneOnTurn: dartbug 13519 /** * A function that is called when uncaught errors are thrown inside the zone. */ // var onError = (dynamic e, dynamic s, LongStackTrace ls) => print('EXCEPTION: $e\n$s\n$ls'); // Type was ZoneOnError: dartbug 13519 LongStackTrace _longStacktrace = null; LongStackTrace _getLongStacktrace(name) { var shortStacktrace = 'Long-stacktraces supressed in production.'; assert((shortStacktrace = _getStacktrace()) != null); return new LongStackTrace(name, shortStacktrace, _longStacktrace); } _getStacktrace() { try { throw []; } catch (e, s) { return s; } } /** * Runs the provided function in the zone. Any runAsync calls (e.g. futures) * will also be run in this zone. * * Returns the return value of body. */ run(body()) { return _zone.run(body); } assertInTurn() { assert(_runningInTurn > 0 || _inFinishTurn); } assertInZone() { assertInTurn(); } }
Constructors
new Zone() #
Creates a new Object instance.
Object instances have no meaningful state, and are only useful through their identity. An Object instance is equal to itself only.
docs inherited from Object
Zone() { _zone = async.Zone.current.fork(specification: new async.ZoneSpecification( run: _onRun, runUnary: _onRunUnary, scheduleMicrotask: _onScheduleMicrotask, handleUncaughtError: _uncaughtError )); }
Properties
var onError #
A function called with any errors from the zone.
var onError = (e, s, ls) => null
var onTurnDone #
A function that is called at the end of each VM turn in which the in-zone code or any runAsync callbacks were run.
var onTurnDone = () => null
Methods
dynamic assertInTurn() #
assertInTurn() { assert(_runningInTurn > 0 || _inFinishTurn); }
dynamic assertInZone() #
assertInZone() { assertInTurn(); }
dynamic run(body()) #
Runs the provided function in the zone. Any runAsync calls (e.g. futures) will also be run in this zone.
Returns the return value of body.
run(body()) { return _zone.run(body); }