RxJava toMultiMap 不适用于房间数据库查询
RxJava toMultiMap not working with room database Query
我正在尝试获取消息映射,作者 ID 键如下:
Map<Long, Collection<Message>>
这是我试过的:
messageViewModel.getAll()
.flatMap(Flowable::fromIterable)
.toMultimap(Message::getAuthorId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onSuccess);
private void onSuccess(Map<Long, Collection<Message>> longCollectionMap) {
Collection<Message> messages = longCollectionMap.get(0);
}
方法messageViewModel.getAll() returns:
Flowable<List<Message>>
然后我将它转换为 Flowable stream(Flowable::fromIterable) 以便它可以一次发出一个项目而不是整个列表,然后我使用 "toMultiMap"[= 进行映射15=]
从来没有调用过onSuccess方法,我不知道这里有什么问题。如果我不使用toMultiMap(并对代码进行相应的修改)它就可以工作,所以问题一定是toMultiMap方法。
但是当我尝试这个时:
List<String> list = Arrays.asList("1", "2", "3");
Flowable.fromIterable(list)
.toMultimap(String::length)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onSuccess);
private void onSuccess(Map<Integer,Collection<String>> integerCollectionMap) {
Collection<String> strings = integerCollectionMap.get(1);
}
这有效!唯一的区别是这个不调用房间数据库来获取可迭代的项目。
文档还说:
Note that this operator requires the upstream to signal {@code onComplete} for the accumulated map to be emitted.
这让我很困惑。由于 Flowable class 没有以 onComplete 作为参数的 subscribe 方法,并且它没有在我上面显示的第二种情况下使用,但它可以工作。
请帮帮我,这快把我逼疯了。
我为遇到相同或类似问题的任何人找到了解决方案。
首先,我必须进行调试以查看映射是否确实完成或根本没有完成。为此,我只是从 toMultiMap 方法开始调试它。然后发现其实是做映射的,所以问题是结果不是returning.
阅读更多关于 RxJava 的内容,我意识到了问题的原因。第一次调用:
messageViewModel.getAll()
正在 return
Flowable<List<Message>>
这意味着此源将发出 0 到 n 个元素,在本例中为 "Lists" 消息。事实上,它发出了消息列表,之后映射就完成了。但它没有 returning 任何东西,因为它正在等待更多 "Lists" 从源头上来。
你必须记住,Flowable 或 Observable 可能会发出无限元素。执行 Flowable.fromIterable 的不同之处在于 fromIterable 将停止,或者在发出作为参数传递的 iterable 的最后一个元素后发出流结束信号,这意味着方法调用序列的其余部分将不会等待更多元素出现,结果将 returned.
所以解决方案是将 messageViewModel.getAll() 的 return 类型更改为:
Single<List<Message>>
所以现在它要么发出 1 个项目,消息列表,要么发出一个错误。因此,在发出一个元素后,将不再出现,链上的其他方法将执行并 return 该值。
但是"toMultiMap"方法对"Single"不起作用,Single class上没有这样的东西。所以你必须把它转换成可流动的,所以我这样做了:
.flatMapPublisher(Flowable::fromIterable)
所以最后代码是这样的:
messageViewModel.getAll() //Returns Single<List<Message>>
.flatMapPublisher(Flowable::fromIterable) // Creates a flowable from List<Message>
.toMultimap(Message::getAuthorId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onSuccess);
非常漂亮和干净的代码,需要一些时间来理解反应式方法的工作原理,但这绝对是值得的。希望有人觉得这有用。
您还可以使用:
Map<Long, Collection<Message>> myMap = messageViewModel.getAll()
.flatMap(message ->
Observable.fromIterable(message)
.toMultimap(Message::getAuthorId)
.toObservable());
我正在尝试获取消息映射,作者 ID 键如下:
Map<Long, Collection<Message>>
这是我试过的:
messageViewModel.getAll()
.flatMap(Flowable::fromIterable)
.toMultimap(Message::getAuthorId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onSuccess);
private void onSuccess(Map<Long, Collection<Message>> longCollectionMap) {
Collection<Message> messages = longCollectionMap.get(0);
}
方法messageViewModel.getAll() returns:
Flowable<List<Message>>
然后我将它转换为 Flowable stream(Flowable::fromIterable) 以便它可以一次发出一个项目而不是整个列表,然后我使用 "toMultiMap"[= 进行映射15=]
从来没有调用过onSuccess方法,我不知道这里有什么问题。如果我不使用toMultiMap(并对代码进行相应的修改)它就可以工作,所以问题一定是toMultiMap方法。
但是当我尝试这个时:
List<String> list = Arrays.asList("1", "2", "3");
Flowable.fromIterable(list)
.toMultimap(String::length)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onSuccess);
private void onSuccess(Map<Integer,Collection<String>> integerCollectionMap) {
Collection<String> strings = integerCollectionMap.get(1);
}
这有效!唯一的区别是这个不调用房间数据库来获取可迭代的项目。
文档还说:
Note that this operator requires the upstream to signal {@code onComplete} for the accumulated map to be emitted.
这让我很困惑。由于 Flowable class 没有以 onComplete 作为参数的 subscribe 方法,并且它没有在我上面显示的第二种情况下使用,但它可以工作。
请帮帮我,这快把我逼疯了。
我为遇到相同或类似问题的任何人找到了解决方案。
首先,我必须进行调试以查看映射是否确实完成或根本没有完成。为此,我只是从 toMultiMap 方法开始调试它。然后发现其实是做映射的,所以问题是结果不是returning.
阅读更多关于 RxJava 的内容,我意识到了问题的原因。第一次调用:
messageViewModel.getAll()
正在 return
Flowable<List<Message>>
这意味着此源将发出 0 到 n 个元素,在本例中为 "Lists" 消息。事实上,它发出了消息列表,之后映射就完成了。但它没有 returning 任何东西,因为它正在等待更多 "Lists" 从源头上来。
你必须记住,Flowable 或 Observable 可能会发出无限元素。执行 Flowable.fromIterable 的不同之处在于 fromIterable 将停止,或者在发出作为参数传递的 iterable 的最后一个元素后发出流结束信号,这意味着方法调用序列的其余部分将不会等待更多元素出现,结果将 returned.
所以解决方案是将 messageViewModel.getAll() 的 return 类型更改为:
Single<List<Message>>
所以现在它要么发出 1 个项目,消息列表,要么发出一个错误。因此,在发出一个元素后,将不再出现,链上的其他方法将执行并 return 该值。
但是"toMultiMap"方法对"Single"不起作用,Single class上没有这样的东西。所以你必须把它转换成可流动的,所以我这样做了:
.flatMapPublisher(Flowable::fromIterable)
所以最后代码是这样的:
messageViewModel.getAll() //Returns Single<List<Message>>
.flatMapPublisher(Flowable::fromIterable) // Creates a flowable from List<Message>
.toMultimap(Message::getAuthorId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onSuccess);
非常漂亮和干净的代码,需要一些时间来理解反应式方法的工作原理,但这绝对是值得的。希望有人觉得这有用。
您还可以使用:
Map<Long, Collection<Message>> myMap = messageViewModel.getAll()
.flatMap(message ->
Observable.fromIterable(message)
.toMultimap(Message::getAuthorId)
.toObservable());