はじめに
UniRxのObservableと、UniTaskはそれぞれ相互変換することができます。
今回はその中でも少し変わった変換パターンを紹介したいと思います。
※ System.LinqUniRxUniRx.Asyncのusingを忘れずに
IEnumerable<UniTask<T>> -> IObservable<T>
複数のUniTask<T>をまとめて、1つのIObservable<T>にする方法です。
やり方が何パターンかあります。
// 対象IEnumerable<UniTask<string>>tasks=CreateSample();// ---// 並列にまとめる(要素の順序を無視して、終わったものから結果を返す)IObservable<string>parallel=tasks.Select(x=>x.ToObservable())// IE<IO<T>>.Merge();// IO<T>// 直列にまとめる(要素の先頭から順番に結果を返す)IObservable<string>sequential=tasks.Select(x=>x.ToObservable())// IE<IO<T>>.Concat();// IO<T>// 全部終わってからまとめて結果をとるなら(IO<IE<T>>)IObservable<IList<string>>whenAll=tasks.Select(x=>x.ToObservable())// IE<IO<T>>.Zip();// IO<IList<T>>// でも、全部まとめてとるならUniTask.WhenAllでいいのでは?UniTask<string[]>whenAll2=UniTask.WhenAll(tasks);UniTask<IEnumerable<T>> -> IObservable<T>
さっきとネストの仕方が逆のパターン。UniTask<IE<T>>を分解して1つのIObservable<T>にする方法です。
2パターンあるけど結果は同じです。
// 対象UniTask<IEnumerable<string>>task=CreateSample();// パターン1IObservable<string>p1=task.ToObservable()// IO<IE<T>>.Select(x=>x.ToObservable())// IO<IO<T>>.Merge();// IO<T>// パターン2IObservable<string>p2=task.ToObservable()// IO<IE<T>>.SelectMany(x=>x.ToObservable());// IO<T>IObservable<T> -> UniTask<IEnumerable<T>>
IObservable<T>が発行するすべてのメッセージを「まとめて」待ち受けるUniTask<T>を作りたい場合。
// 対象IObservable<string>observable=CreateSample();// ToArray()してからToUniTask()でOKUniTask<string[]>task=observable.ToArray().ToUniTask();IObservable<UniTask<T>> -> IObservable<T>
ObservableがUniTaskを扱う場合に、それを1つのObservableにまとめる。
// 対象IObservable<UniTask<string>>observable=CreateSample();// 並列(終わった順に結果を出すなら)IObservable<string>parallel=observable.SelectMany(x=>x.ToObservable());// 直列(もとのIO<T>から発行された順序を維持するなら)IObservable<string>sequential=observable.Select(x=>x.ToObservable()).Concat();IObservable<UniTask<T>> -> UniTask<IEnumerable<T>>
ObservableがUniTaskを扱う場合に、それをUniTask側にまとめる。
IObservable<UniTask<string>>observable=CreateSample();// 結果は先に終わったUniTaskの順番になるUniTask<string[]>task=observable.SelectMany(x=>x.ToObservable())// IO<IO<T>>.Merge()// IO<T>.ToArray()// IO<T[]>.ToUniTask();// UniTask<T[]>UniTask<IObservable<T>> -> IObservable<T>
UniTaskの中にObservableが入り込んじゃった場合。
// 対象UniTask<IObservable<string>>task=CreateSample();// taskをIO<IO<T>>に変換してからMerge()IObservable<string>observable=task.ToObservable().Merge();UniTask<IObservable<T>> -> UniTask<IEnumerable<T>>
UniTaskの中にObservableが入り込んじゃったものを、今度はUniTask側にまとめる場合。
// async/await使っちゃうのが楽privateasyncUniTask<IEnumerable<string>>Unwrap(UniTask<IObservable<string>>task){varobservable=awaittask;returnawaitobservable.ToArray();}IObservable<IObservable<T>> -> UniTask<IEnumerable<T>>
こんなシチュエーションあるのかよくわからないけど。
IObservable<IObservable<string>>observable=CreateSample();UniTask<string[]>task=observable.SelectMany(x=>x)// IO<T>.ToArray()// IO<T[]>.ToUniTask();// UniTask<T[]>まとめ
UniRxとUniTaskはだいたいどんなパターンでもそれぞれに変換することができます。
両者を組み合わせて使い、必要に応じて変換をかけるとよいでしょう。