取消订阅另一个异步版Observable
中的异步flatMap
的最佳(干净)方法是什么?
说,我有一个演示文稿,显示用户的聊天列表。
每个聊天项目都应显示自己的最新消息。
这是一个原始代码来说明:
fun AsyncInsideAsync() {
/**
* A chat that 'transmits' latest message
*/
class Chat(val name: Int) {
val lastMessage: PublishSubject<String> = PublishSubject.create()
fun postMessage(message: Int) {
lastMessage.onNext("Chat: $name, Message: $message")
}
}
// List of chats for user.
val chats: PublishSubject<Chat> = PublishSubject.create()
///////////////////////////////////
// ORIGINAL SEQUENCE //
///////////////////////////////////
val sequence = chats.flatMap { it.lastMessage }
val subscriber = TestSubscriber<String>()
sequence.subscribe(subscriber)
// User has single chat in a chat-list
val chat1 = Chat(1)
chats.onNext(chat1)
// Someone posts a message in Chat 1
chat1.postMessage(1)
subscriber.assertValues(
"Chat: 1, Message: 1"
)
// Someone posts another message
chat1.postMessage(2)
subscriber.assertValues(
"Chat: 1, Message: 1",
"Chat: 1, Message: 2"
)
// Chat 1 disappears FROM USER CHAT LIST, Chat 2 is created
val chat2 = Chat(2)
chats.onNext(chat2)
// Someone posts a message to Chat 2
chat2.postMessage(1)
subscriber.assertValues(
"Chat: 1, Message: 1",
"Chat: 1, Message: 2",
"Chat: 2, Message: 1"
)
// Someone out there posts a message to Chat 1 that is not visible to user anymore
chat1.postMessage(3)
// The answer looks like this
// "Chat: 1, Message: 1",
// "Chat: 1, Message: 2",
// "Chat: 2, Message: 1",
// "Chat: 1, Message: 3"
// Chat 1 is still subscribed and test fails
subscriber.assertValues(
"Chat: 1, Message: 1",
"Chat: 1, Message: 2",
"Chat: 2, Message: 1",
)
}
我想到的是使用一个主题(或共享的可观察对象)来制造一系列内部订阅。但它看起来很奇怪:
///////////////////////////////////
// MODIFIED SEQUENCE //
///////////////////////////////////
val unsubscribe: PublishSubject<Boolean> = PublishSubject.create()
val sequence = chats
.doOnNext({ unsubscribe.onNext(true) })
.doAfterTerminate({ unsubscribe.onNext(true) })
.flatMap {
it.lastMessage.takeUntil(unsubscribe)
}
这种方法有效,但看起来很可怕。 非常感谢!
答案 0 :(得分:2)
假设评论
// Chat 1 disappears FROM USER CHAT LIST, Chat 2 is created
表示您希望当前Chat
(在这种情况下为chat1
)在Chat
上发送新的chats
时停止发出,您可以使用switchMap
运算符完成此操作。
val sequence = chats.switchMap { it.lastMessage }
来自ReactiveX文档:
RxJava还实现了switchMap运算符。它表现得很像 flatMap,除了源每次发出新项目 可观察,它将取消订阅并停止镜像Observable 这是从先前发出的项目生成的,仅从头开始 反映当前的一个。