flutter future源码架构及分析

231 阅读3分钟

1.future 架构图

future.jpg

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

  1. _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);
      });
    }
  }   
  1. Future 标记状态
  • 把任务标记为 then catchError whenComplete 三种状态
  • 任务状态设置complete 状态时, 会结束向链表中添加数据, 并开始遍历链表执行回调
  void _setValue(T value) {
    _state = _stateValue;
  }
  
  void _setErrorObject(AsyncError error) {
    _state = _stateError;
  }
    
  void _setPendingComplete() {
    _state = _statePendingComplete;
  }
  1. Future 执行_FutureListener 链表中的回调
  • _propagateToListeners 是一个while循环, 当Future._state满足其中条件时执行相应的函数
  • setValue setError setPendingComplete 会修改相应的状态
  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 同理