zone.dart阅读
2020-09-19 本文已影响0人
嘛尼嘛哄
Zone的相关类如下
- 继承关系
_Zone (dart.async)
_RootZone (dart.async) //启动时main函数在这个zone下执行
_CustomZone (dart.async) //主要用于处理其他microtask,可以有多个
- 函数关联:
在普通函数的基础层上做了一层包装,叫做ZoneFunction
,它主要是将函数的上下文添加到一个独立的空间,函数的堆栈信息和事件回调在这个Zone里面运行,如果有处理不了的错误则会抛出给它的assent
Zone处理,根据函数参数的不同构造了如下的ZoneFunction
class _ZoneFunction<T extends Function> {
...
class _RunNullaryZoneFunction {
...
class _RunUnaryZoneFunction {
...
class _RunBinaryZoneFunction {
...
class _RegisterNullaryZoneFunction {
...
class _RegisterUnaryZoneFunction {
...
class _RegisterBinaryZoneFunction {
- 函数执行结果的CallBack:
名字都很有规律,根据不同的Zone函数的执行结果的返回值封装了各种callback类型,提高代码的可读性
typedef R ZoneCallback<R>();
typedef R ZoneUnaryCallback<R, T>(T arg);
typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2);
typedef HandleUncaughtErrorHandler = void Function(Zone self,
ZoneDelegate parent, Zone zone, Object error, StackTrace stackTrace);
typedef RunHandler = R Function<R>(
Zone self, ZoneDelegate parent, Zone zone, R Function() f);
typedef RunUnaryHandler = R Function<R, T>(
Zone self, ZoneDelegate parent, Zone zone, R Function(T arg) f, T arg);
typedef RunBinaryHandler = R Function<R, T1, T2>(Zone self, ZoneDelegate parent,
Zone zone, R Function(T1 arg1, T2 arg2) f, T1 arg1, T2 arg2);
typedef RegisterCallbackHandler = ZoneCallback<R> Function<R>(
Zone self, ZoneDelegate parent, Zone zone, R Function() f);
typedef RegisterUnaryCallbackHandler = ZoneUnaryCallback<R, T> Function<R, T>(
Zone self, ZoneDelegate parent, Zone zone, R Function(T arg) f);
typedef RegisterBinaryCallbackHandler
= ZoneBinaryCallback<R, T1, T2> Function<R, T1, T2>(Zone self,
ZoneDelegate parent, Zone zone, R Function(T1 arg1, T2 arg2) f);
typedef AsyncError ErrorCallbackHandler(Zone self, ZoneDelegate parent,
Zone zone, Object error, StackTrace stackTrace);
typedef void ScheduleMicrotaskHandler(
Zone self, ZoneDelegate parent, Zone zone, void f());
typedef Timer CreateTimerHandler(
Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f());
typedef Timer CreatePeriodicTimerHandler(Zone self, ZoneDelegate parent,
Zone zone, Duration period, void f(Timer timer));
typedef void PrintHandler(
Zone self, ZoneDelegate parent, Zone zone, String line);
typedef Zone ForkHandler(Zone self, ZoneDelegate parent, Zone zone,
ZoneSpecification specification, Map zoneValues);
-
ZoneSpecification
:
描述了Zone的规范, 定义了Zone所需要的方法, 用来在复写某个Zone, 在fork方法中会介绍
//全新的 `ZoneSpecification` ,这些方法在 `Zone` 都有定义
const factory ZoneSpecification(
{HandleUncaughtErrorHandler handleUncaughtError,
RunHandler run,
RunUnaryHandler runUnary,
RunBinaryHandler runBinary,
RegisterCallbackHandler registerCallback,
RegisterUnaryCallbackHandler registerUnaryCallback,
RegisterBinaryCallbackHandler registerBinaryCallback,
ErrorCallbackHandler errorCallback,
ScheduleMicrotaskHandler scheduleMicrotask,
CreateTimerHandler createTimer,
CreatePeriodicTimerHandler createPeriodicTimer,
PrintHandler print,
ForkHandler fork}) = _ZoneSpecification;
//根据传入的参数拷贝一个 `ZoneSpecification`
factory ZoneSpecification.from(ZoneSpecification other,
...
-
ZoneDelegate
:
“从名字上来看它就是一个代理,通过代理指定当前Zone的相关方法,它和上面的ZoneSpecification
(通过override某个Zone的方式来相关的方法),将ParentZone设置为 delegate
, Flutter文档中推荐使用delegate, 理由是delegate能很直接访问当前Zone中已经初始化的数据, 并且能直接找到需要执行代理的Zone”
ZoneDelegate (dart.async)
_ZoneDelegate (dart.async)
...
abstract class ZoneDelegate {
void handleUncaughtError(Zone zone, error, StackTrace stackTrace);
R run<R>(Zone zone, R f());
R runUnary<R, T>(Zone zone, R f(T arg), T arg);
R runBinary<R, T1, T2>(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2);
ZoneCallback<R> registerCallback<R>(Zone zone, R f());
ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(Zone zone, R f(T arg));
ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>(
Zone zone, R f(T1 arg1, T2 arg2));
AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace);
void scheduleMicrotask(Zone zone, void f());
Timer createTimer(Zone zone, Duration duration, void f());
Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer));
void print(Zone zone, String line);
Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues);
}
-
_ZoneDelegate
:
具体实现如下:
//获取_parent是否有设置delegate
ZoneDelegate _parentDelegate(_Zone zone) {
if (zone.parent == null) return null;
return zone.parent._delegate;
}
class _ZoneDelegate implements ZoneDelegate {
//1.授权目标,就是持有这个delegate的Zone
final _Zone _delegationTarget;
_ZoneDelegate(this._delegationTarget);
//2. 所有执行方法集中到handler处理
void handleUncaughtError(Zone zone, error, StackTrace stackTrace) {
//前面提到过每个ZoneFunction都会持有一个Zone,这个也不例外
var implementation = _delegationTarget._handleUncaughtError;
//这个Zone是我们在外部注册这个函数实现的传入Zone,最终结果也需要在这个Zone上返回
_Zone implZone = implementation.zone;
//提取外部注册的函数
HandleUncaughtErrorHandler handler = implementation.function;
//这里有3个Zone,当前执行的Zone,parentZone,执行是传入的zone
return handler(
implZone, _parentDelegate(implZone), zone, error, stackTrace);
}
//和上面的方法实现类似
R run<R>(Zone zone, R f()) { ...
R runUnary<R, T>(Zone zone, R f(T arg), T arg) { ...
R runBinary<R, T1, T2>(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) {..
ZoneCallback<R> registerCallback<R>(Zone zone, R f()) { ...
ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(Zone zone, R f(T arg)) { ...
ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( ...
AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace) {
ArgumentError.checkNotNull(error, "error");
var implementation = _delegationTarget._errorCallback;
_Zone implZone = implementation.zone;
//此处有针对 `RootZone` 有特殊处理,_rootZone直接处理
if (identical(implZone, _rootZone)) return null;
ErrorCallbackHandler handler = implementation.function;
return handler(
implZone, _parentDelegate(implZone), zone, error, stackTrace);
}
void scheduleMicrotask(Zone zone, f()) { ...
Timer createTimer(Zone zone, Duration duration, void f()) { ...
Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)) {...
void print(Zone zone, String line) { ...
Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues) {...
}
-
_Zone
:
抽象类, 解藕, 定义了属性的便利获取方法, Zone比较
Zone(区域, 分区)
- Zone代表着一个独立区域, 所有的isolae入口函数
main
,spawned functions
都是在rootZone中运行的, 如果还没有创建CustomZone, 剩下的命令则也继续运行在currentZone。 - 可以看出
rootZone
是用来执行一些重要的操作, 优先级比较高。 - Zone作为一个抽象类, 它定义了子类Zone所的所有行为操作,例如
registerCalback
来执行一般功能的的回调事件, 关联在当前Zone下的钩子函数, 只能通过当前绑定注册的Zone下面区回调 - scheduleMicrotask, 开启一个微task任务, 直接和系统底层交互来实现所需执行的操作
Zone 属性和方法介绍
abstract class Zone {
//1. 将默认构造方法添加 `_` 前最,私有化,用于构造单利类
Zone._();
//2. 初始化一个rootZone
static const Zone root = _rootZone; // const _rootZone = const _RootZone();
//3. 用于缓存当前执行的zone
static Zone _current = _rootZone;
static Zone get current => _current;
/**
4. 处理异步执行的错误事件,一般归为2类
- Timer.run执行过程中出现异常,主动调用throw抛出异常
- 异步的Stream/Future执行出现异常,当调用他们的 `catchError` 方法时会触发Zone的 `handleUncaughtError` 函数
从而得到我们所需要的异常堆栈信息
*/
void handleUncaughtError(error, StackTrace stackTrace);
//5. 当前Zone的ParentZone,RootZone没有PrarentZone,它通通过[fork]一个已经存在的 `Zone` 或者是[runZoned]方法复制一个当前的 `Zone` ,那么parent就是它所复制的 `Zone`
Zone get parent;
//6. 获取当前最近的错误处理的zone,如果没有就返回的parent
Zone get errorZone;
bool inSameErrorZone(Zone otherZone);
//7. 创建一个child zone,child zone使用给定的工厂函数 `ZoneSpecification` 来重parentZone的方法
// 新的zone继承了存储的values,通过[operater[]]函数获取,并且从[zoneValues]中更新它们,是否需要被提阿昏
Zone fork({ZoneSpecification specification, Map zoneValues});
//8. Zone执行的几个方法,方法都很有规律,得看具体实现
R run<R>(R action()); //普通执行,没有异常捕捉
R runUnary<R, T>(R action(T argument), T argument); //函数名是否和参数个数有关?
R runBinary<R, T1, T2>(
R action(T1 argument1, T2 argument2), T1 argument1, T2 argument2); //函数名是否和参数个数有关?
void runGuarded(void action());//带保护的执行,可以捕捉异常,相当于 `try{ run((){..})} cach {}`
void runUnaryGuarded<T>(void action(T argument), T argument);
void runBinaryGuarded<T1, T2>(
void action(T1 argument1, T2 argument2), T1 argument1, T2 argument2);
//9. 注册给定Zone的callback事件回掉,当实现一个异步回调的时候,callback必须使用[registerCallback]注册,并在此方法里执行异步回调,同时可以记录当前的函数执行堆栈,方便在事件回调的时候打印
ZoneCallback<R> registerCallback<R>(R callback());
ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(R callback(T arg));
ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>(
R callback(T1 arg1, T2 arg2));
//10. 注册执行的callback到Zone中,并返回一个ZoneCallBack,当这个zone执行这个callback的时候就会执行这个返回的Callback,暂时理解为一个钩子函数吧
ZoneCallback<R> bindCallback<R>(R callback());
ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R callback(T argument));
ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>(
R callback(T1 argument1, T2 argument2));
void Function() bindCallbackGuarded(void callback());
void Function(T) bindUnaryCallbackGuarded<T>(void callback(T argument));
void Function(T1, T2) bindBinaryCallbackGuarded<T1, T2>(
void callback(T1 argument1, T2 argument2));
// 11. 拦截主动发出的error事件,如 `Completer.completeError` , `StreamController.addError`
// 拦截构造函数直接抛出的error,如 `Future.error` , `Future.sync`
AsyncError errorCallback(Object error, StackTrace stackTrace);
//Runs [callback] asynchronously in this zone.
void scheduleMicrotask(void callback());
//Creates a Timer where the callback is executed in this zone.
Timer createTimer(Duration duration, void callback());
//Creates a periodic Timer where the callback is executed in this zone.
Timer createPeriodicTimer(Duration period, void callback(Timer timer));
// 12.我们所打印的全局的print方法,委托给了当前Zone的prindt方法去执行
void print(String line);
// 13.进去一个新的Zone,新的Zone被设置为 `_current`
static Zone _enter(Zone zone) {
assert(zone != null);
assert(!identical(zone, _current));
Zone previous = _current;
_current = zone;
return previous;
}
static void _leave(Zone previous) {
assert(previous != null);
Zone._current = previous;
}
//获取当前Zone中保存的value,在前面的forkZone中有提到过
operator [](Object key);
}
_RootZone
-
_RootZone
:
//切换Zone执行,执行完成后返回前面的Zone,将函数的执行的上下文环境放到单独的Zone中执行
R _rootRun<R>(Zone self, ZoneDelegate parent, Zone zone, R f()) {
if (Zone._current == zone) return f();
Zone old = Zone._enter(zone);
try {
return f();
} finally {
Zone._leave(old);
}
}
R _rootRunUnary<R, T>( ...
...
//执行 `_RootZone的微task` , 开启了一个callback的事件循环
void _rootScheduleMicrotask(
Zone self, ZoneDelegate parent, Zone zone, void f()) {
if (!identical(_rootZone, zone)) {
bool hasErrorHandler = !_rootZone.inSameErrorZone(zone);
if (hasErrorHandler) {
f = zone.bindCallbackGuarded(f);
} else {
f = zone.bindCallback(f);
}
// Use root zone as event zone if the function is already bound.
zone = _rootZone;
}
_scheduleAsyncCallback(f);
}
// `_nextCallback` 和 `_lastCallback` 为全局变量,当开启 `_startMicrotaskLoop` 循环时,当前Zone pending在此次Callback中,知道执行完毕
void _scheduleAsyncCallback(_AsyncCallback callback) {
_AsyncCallbackEntry newEntry = new _AsyncCallbackEntry(callback);
if (_nextCallback == null) {
_nextCallback = _lastCallback = newEntry;
if (!_isInCallbackLoop) {
//
_AsyncRun._scheduleImmediate(_startMicrotaskLoop);
}
} else {
_lastCallback.next = newEntry;
_lastCallback = newEntry;
}
}
void _startMicrotaskLoop() {
_isInCallbackLoop = true;
try {
// Moved to separate function because try-finally prevents
// good optimization.
_microtaskLoop();
} finally {
_lastPriorityCallback = null;
_isInCallbackLoop = false;
if (_nextCallback != null) {
//承接上文
_AsyncRun._scheduleImmediate(_startMicrotaskLoop);
}
}
}
//立即开启一个callback,
class _AsyncRun {
/** Schedule the given callback before any other event in the event-loop. */
external static void _scheduleImmediate(void callback());
}
class _RootZone extends _Zone {
const _RootZone();
//方法获取
_RunNullaryZoneFunction get _run =>
const _RunNullaryZoneFunction(_rootZone, _rootRun);
...
_Zone get parent => null;
//存储当前Zone中定义的值
Map get _map => _rootMap;
static final _rootMap = new HashMap();
ZoneDelegate get _delegate {
if (_rootDelegate != null) return _rootDelegate;
return _rootDelegate = new _ZoneDelegate(this);
}
//获取最近的error handler Zone,rootZone只能是它本身
Zone get errorZone => this;
//1.所有带有 guard(警戒/保护)都会提前判定是否在同一个zone,如果不是则抛出异常.
void runGuarded(void f()) {
try {
if (identical(_rootZone, Zone._current)) {
f();
return;
}
_rootRun(null, null, this, f);
} catch (e, s) {
handleUncaughtError(e, s);
}
}
void runUnaryGuarded<T>(void f(T arg), T arg) {...
void runBinaryGuarded<T1, T2>(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) {..
//2. 函数传递,包装方法
ZoneCallback<R> bindCallback<R>(R f()) { ...
ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg)) { ...
ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( ...
void Function() bindCallbackGuarded(void f()) { ...
void Function(T) bindUnaryCallbackGuarded<T>(void f(T arg)) { ...
void Function(T1, T2) bindBinaryCallbackGuarded<T1, T2>( ...
// zone[key] 总是为null
operator [](Object key) => null;
...
//2.不带保护,执行
R run<R>(R f()) {
//如果是currentZone,就不用切换currentZone直接执行
if (identical(Zone._current, _rootZone)) return f();
return _rootRun(null, null, this, f);
}
R runUnary<R, T>(R f(T arg), T arg) {
R runBinary<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) {
//3.当前为RootZone,不需要关联其他Zone的环境再执行,直接返回
ZoneCallback<R> registerCallback<R>(R f()) => f;
ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(R f(T arg)) => f;
ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>(
R f(T1 arg1, T2 arg2)) =>
f;
AsyncError errorCallback(Object error, StackTrace stackTrace) => null;
//开启一个Microtask,一个callback的eventLoop,具有较高的优先级
void scheduleMicrotask(void f()) {
//主要实现在这个方法 `_AsyncRun._scheduleImmediate(_startMicrotaskLoop);`
_rootScheduleMicrotask(null, null, this, f);
}
//Timer是一个外部函数实现,在RootWidget attach的时候也调用了此方法
Timer createTimer(Duration duration, void f()) { ...
Timer createPeriodicTimer(Duration duration, void f(Timer timer)) {
void print(String line) {
//part of dart._internal;
printToConsole(line);
}
}
_CustomZone
class _CustomZone extends _Zone {
final _Zone parent;
final Map _map;
//懒加载生ZoneDelegate -> this -> this._parent
ZoneDelegate get _delegate {
if (_delegateCache != null) return _delegateCache;
_delegateCache = new _ZoneDelegate(this);
return _delegateCache;
}
//1. 根据parentZone,Zone的定义参数,以及需要传入到前Zone的的参数初始化
_CustomZone(this.parent, ZoneSpecification specification, this._map) {.
_run = (specification.run != null)
? new _RunNullaryZoneFunction(this, specification.run)
: parent._run;
...
}
//_handleUncaughtError
Zone get errorZone => _handleUncaughtError.zone;
// 同上 `_RootZone`
void runGuarded(void f()) { ..
...
void Function(T1, T2) bindBinaryCallbackGuarded<T1, T2>(
operator [](Object key) {
//当前Zone中查找
if (result != null || _map.containsKey(key)) return result;
//parent中查找
if (parent != null) {
//如果都找不到就是_rootZone;
assert(this == _rootZone);
return null;
}
// Methods that can be customized by the zone specification.
// 根据 ` zone specification` 对需要parent的自定义方法进行替换,
void handleUncaughtError(error, StackTrace stackTrace) { ...
Zone fork({ZoneSpecification specification, Map zoneValues}) { ...
R run<R>(R f()) { ...
R runUnary<R, T>(R f(T arg), T arg) { ..
void scheduleMicrotask(void f()) { ..
Timer createTimer(Duration duration, void f()) {...
Timer createPeriodicTimer(Duration duration, void f(Timer timer)) { ...
void print(String line) { ...
}
小结
-
根据代码实现来看, Zone表示的是代码执行的环境, 通过Zone的机制, 将函数执行的上下文堆栈信息和回调方法单独处理,实际理解起来还需要和Isolate的实现原理相结合.
-
TODO: 未完待续
-
可以看到很多方法最终调用到
external static
就找不到具体实现了, -
要完全理解整个流程还需要继续研究 flutter engine层的相关代码