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 出去了(滑稽脸)
至此 迷案告破...