我正在使用RxSwift来包装移动应用程序的服务器同步过程。我有一个Observable<RemoteEvent>
包装一个websocket连接,并以Event
的形式发出收到的每条消息。同样,我有Observable<SynchronizationResult>
包装API同步过程。一旦我的应用程序打开WebSocket连接,服务器就会发送hello
消息。收到该消息后,我想启动同步过程并缓冲所有事件,直到同步完成。这是我在努力的地方。目前,我有:
self.eventStreamService.observe(connection).scan((nil, [])) { (state, event) -> (Observable<RemoteEvent>?, [RemoteEvent]) in
guard event.type == "hello" else {
return (state.0?.concat(Observable.just(event)), state.1 + [event])
}
// This is the sync operation
return (
self.synchronizationService
.synchronize(ConnectionSynchronizationContext(connection: connection), lightweight: true)
.toArray()
.flatMap { results -> Observable<RemoteEvent> in
(state.1 + [event]).toObservable()
},
[]
)
}
.flatMapLatest { $0.0 ?? Observable.empty() }
尽管这很丑陋,但它也有一个重大错误:任何传入事件导致重新订阅同步Observable
,然后重新启动整个同步过程。我确信必须有更好的方法来做到这一点。
答案 0 :(得分:2)
以下是您可以获得所需功能的方法:
// this is a stub for the purpose of the example
let interval = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
let websocketEvents = interval
.map { i -> String in
if i == 1 {
return "hello"
} else {
return String(i)
}
}
.replayAll()
websocketEvents.connect()
func performSync() -> Observable<Void> {
return Observable<Void>.create { o in
print("starting sync")
// actually start sync with server
// ....
delay(2.0) {
print("sync finished")
o.onNext(())
}
return NopDisposable.instance
}
}
// websocket events as they come, regardless of sync status
websocketEvents
.subscribeNext { e in
print("websocket event received: \(e)")
}
// all websocket events, buffered and only emitted post-sync
websocketEvents
.filter { $0 == "hello" }
.flatMapLatest { _ in performSync() }
.flatMapLatest { _ in websocketEvents }
.subscribeNext { e in
print("websocket event post sync: \(e)")
}
这将输出:
收到websocket活动:0
收到websocket活动:你好 开始同步
收到websocket事件:2
收到websocket活动:3
同步完成
websocket事件后同步:0
websocket事件后同步:你好 websocket事件后同步:2
websocket事件后同步:3
收到websocket活动:4
websocket事件后同步:4
收到websocket活动:5
websocket事件后同步:5