RxJava2中如何避免嵌套Single对象?新手求解决方案
解决RxJava中嵌套Single的问题
你现在遇到的是RxJava里典型的嵌套Observable场景,用map操作符处理返回Single的函数时,会把外层的Single包装成Single<Single<...>>,这显然不是你想要的结构。解决这个问题的核心是用flatMap替代第一个map,它能帮你“展开”嵌套的Single,让数据流回归线性。
问题分析
你的原代码:
tickHappened.map{ func(it) } // 得到 Single<Single<ArrayList<String>>> .map { single -> single.map { list -> list.size } } // 最后是 Single<Single<Int>>
这里的两层map只是把嵌套的Single又包了一层,并没有真正解决嵌套问题,最终还是得到了嵌套的Single<Single<Int>>,而你需要的是直接的Single<Int>。
正确解决方案
把第一个map换成flatMap,它会自动订阅内层的Single,并把内层Single发射的数据传递到下游:
tickHappened.flatMap { func(it) } // 展开后得到 Single<ArrayList<String>> .map { list -> list.size } // 直接对列表处理,得到 Single<Int>
为什么这么做?
map操作符的作用是转换数据类型,它会把上游的每个元素转换成另一个对象——哪怕这个对象是Observable/Single,它也只会原样传递,所以就产生了嵌套。flatMap操作符的作用是转换并展开数据流:当你返回一个Single时,它会自动订阅这个Single,把Single内部发射的结果(也就是ArrayList<String>)作为下游的数据源,这样就彻底消除了嵌套结构,让链式调用更清晰。
如果你需要保证数据流的顺序(虽然Single只会发射一次数据,顺序影响不大),也可以用concatMap,它和flatMap的区别是会严格按照上游的顺序处理每个元素,不过对于Single场景来说,两者效果几乎一致。
内容的提问来源于stack exchange,提问作者Mangat Rai Modi
相关产品推荐
相关产品推荐

