UniRx---源码阅读提示 FromCoroutine

UniRx---源码阅读提示 FromCoroutine

先上函数

  public static IObservable<Unit> FromCoroutine(Func<IEnumerator> coroutine, bool publishEveryYield = false)
 {
    return FromCoroutine<Unit>((observer, cancellationToken) => WrapEnumerator(coroutine(), observer, cancellationToken, publishEveryYield));
 }

这个静态函数就是平时从Observable点出来,用来将一个协程转换为一个Observable(发射源)的那个,参数publishEveryYield默认为False,意思是只在协程结束的时候发射一次,如果为true,则在协程每次yield和结束的时候 发射一次。

下面稍微深入剖析一下这个接口的实现细节

首先return的这个函数里的那个参数让人头很晕,我们来理一下。

这个参数是一个回调  回调的类型是这样的  Fun<observer<unit>,cancellationToken,Ienumerator>  (提一嘴,unit是UniRx的空数据类型)

然后,搞清楚 这个回调是在哪里调的,f12跟进后,发现这个回调被传进了一个FromCorouineObservable里了。

 public static IObservable<T> FromCoroutine<T>(Func<IObserver<T>, CancellationToken, IEnumerator> coroutine)
        {
            return new UniRx.Operators.FromCoroutineObservable<T>(coroutine);
        }

这个东西我们第一次见但很熟悉....因为他继承自OperatorObservableBase ,所以先下关注SubscribeCore

继续跟进后发现,没有啥特别的,单纯的封装一下Observer ,而那个回调需要的什么什么cancelToken也是就地构造传进去的

所以我们的关注点又来到了 那个回调上 ,我们现在很明确这个回调的返回值 就是最后交代出去并开启的那个协程

关注点来到 回调里的包装函数 源代码就不贴了 很长一大串,这种Ienumerator返回值的函数会被编译器编译成类

而对他的调用 实际上就是构造了一个可迭代对象。现在终于理出了头绪,这个WrapEnumerator就是最终的那个协程,

现在让我们进去看看,他做了点什么。

做的事情除了异常捕获那些,其实很简单,就是手动调用原始Ienumerator的moveNext方法 然后把current给yield return 出去

相当于就是 把原来直接yield return 出去的东西 先拆开来看了一眼,然后把拆出来的东西 yield return 出去了(滑稽脸)

至此 迷案告破...