1.future 架构图
2.Zone 分析
在 Dart 中,Zone 是一种用于管理异步操作的机制。Zone 提供了一种将代码封装在一个特定上下文中执行的方式。它可以用来捕获和处理异步操作中的错误、修改调度行为、设置错误处理程序等。
当一个 Future 的任务被添加到 Zone 中时,它将在独立的执行上下文中执行,而不会阻塞当前线程的执行。这意味着在执行 Future 的任务期间,其他任务仍然可以继续在事件循环中执行,从而实现了非阻塞的异步操作。
- 如 run 开始运行
- 如 callback 插入回调
- 如 fork 开辟子Zone
举一个修改调度行为的例子
void main() {
// 创建自定义的 ZoneSpecification 对象
var myZone = ZoneSpecification(scheduleMicrotask: (self, parent, zone, f) {
print('Before scheduling microtask');
// 在调度微任务之前执行自定义逻辑
self.scheduleMicrotask(zone, () {
print('Inside scheduled microtask');
f?.call();
});
});
// 使用 runZoned 创建一个指定了特定 ZoneSpecification 的 Zone
runZoned(() {
scheduleMicrotask(() {
print('Inside original microtask');
});
}, zoneSpecification: myZone);
}
/// 执行结果
// Before scheduling microtask
// Inside scheduled microtask
// Inside original microtask
分析: 通过使用 ZoneSpecification,我们可以修改调度行为以添加自定义逻辑,并在调度微任务或其他异步操作之前或之后执行额外的代码。这样我们可以对异步操作进行更精细的控制和定制。
ZoneDelegate 类似对以上代码的执行过程插入一些监听
1.handleUncaughtError可以捕获代码执行过程中的异常,因为Future是异步任务正常的try-catch是无法捕获异常
2.任务完成时通知future改变状态
3. _FutureListener
- _FutureListener? _nextListener 可见是一个链表
- final Function? callback 回调函数
- final Function? errorCallback 失败回调
- final int state 标记
- final _Future result 监听的对象
因此_FutureListener 就是一个监听者对象, 每个Listener 可能是 then error complete 其中一种, 并以state 为标记
_FutureListener.then
_FutureListener.thenAwait
_FutureListener.catchError
_FutureListener.whenComplete
4. _Future
- _Future 添加_FutureListener, 通过下面的构造方法, 分别构建响应的_FutureListener实例
- 本质就是链表添加节点, 每个listener就是一个节点
- 添加节点又分两种情况:
-
_mayAddListener 即 只要没有标记为_statePendingComplete , 就链表添加节点
-
否则 开始执行链表中的回调
-
_statePendingComplete 为状态(state), 详见下文
-
Future<R> then<R>(FutureOr<R> f(T value), {Function? onError}) {
_Future<R> result = new _Future<R>();
_addListener(new _FutureListener<T, R>.then(result, f, onError));
return result;
}
Future<E> _thenAwait<E>(FutureOr<E> f(T value), Function onError) {
_Future<E> result = new _Future<E>();
_addListener(new _FutureListener<T, E>.thenAwait(result, f, onError));
return result;
}
Future<T> catchError(Function onError, {bool test(Object error)?}) {
_Future<T> result = new _Future<T>();
_addListener(new _FutureListener<T, T>.catchError(result, onError, test));
return result;
}
Future<T> whenComplete(dynamic action()) {
_Future<T> result = new _Future<T>();
_addListener(new _FutureListener<T, T>.whenComplete(result, action));
return result;
}
/// 添加
void _addListener(_FutureListener listener) {
if (_mayAddListener) {
listener._nextListener = _resultOrListeners;
_resultOrListeners = listener;
} else {
_zone.scheduleMicrotask(() {
_propagateToListeners(this, listener);
});
}
}
- Future 标记状态
- 把任务标记为 then catchError whenComplete 三种状态
- 任务状态设置complete 状态时, 会结束向链表中添加数据, 并开始遍历链表执行回调
void _setValue(T value) {
_state = _stateValue;
}
void _setErrorObject(AsyncError error) {
_state = _stateError;
}
void _setPendingComplete() {
_state = _statePendingComplete;
}
- Future 执行_FutureListener 链表中的回调
- _propagateToListeners 是一个while循环, 当Future._state满足其中条件时执行相应的函数
setValuesetErrorsetPendingComplete会修改相应的状态
static void _propagateToListeners(
_Future source, _FutureListener? listeners) {
while (true) {
/// 遍历监听器链表
_FutureListener listener = listeners;
_FutureListener? nextListener = listener._nextListener;
while (nextListener != null) {
listener._nextListener = null;
_propagateToListeners(source, listener);
listener = nextListener;
nextListener = listener._nextListener;
}
/// WhenComplete
void handleWhenCompleteCallback() {
var completeResult;
completeResult = listener.handleWhenComplete();
}
/// then
void handleValueCallback() {
listenerValueOrError = listener.handleValue(sourceResult);
}
/// catchError
void handleError() {
listenerValueOrError = listener.handleError(asyncError);
}
/// 根据Future 标记的状态 执行响应的回调函数
if (listener.handlesComplete) {
handleWhenCompleteCallback();
} else if (!hasError) {
if (listener.handlesValue) {
handleValueCallback();
}
} else {
if (listener.handlesError) {
handleError();
}
}
}
5. 应用
Future<T> reduce(T combine(T previous, T element)) {
// 1. 创建future, 忽略一些判断
_Future<T> result = new _Future<T>();
// 2.调用result._complete/_completeError
StreamSubscription<T> subscription =
this.listen(null, onError: result._completeError, onDone: () {
// 忽略其他实现
result._complete(value);
}, cancelOnError: true);
subscription.onData((T element) {
// 忽略其他实现
future._completeError(error, stackTrace);
});
// 3. 返回future
return result;
}
3.3 _Completer
Completer.complete 触发Futrue.completeValue 即 value 有值了
Completer.completeError 同理