我不太确定如何正确地做到这一点,而且我可能错过了一些关于FRP的概念,因为我不久以来一直在玩ReactiveCocoa。
我的情况是这样的 - 我有信号:
我希望有一个我可以订阅的信号,它将:
所有这一切背后的想法是我的主要加载对象信号应返回对象的初始版本(如本地存储),同时从远程存储更新该对象,最后发送更新的版本。因此,最终订阅者应该在完成之前两次接收该对象。
远程加载信号取决于本地加载信号,因为我们必须加载本地对象才能获取对象的remoteId。因此,我想避免在启动信号时两次加载本地对象(一次用于发送到原始订户,一次用于获取remoteId以加载远程对象)。
我想出的初始解决方案是使本地负载信号成为多播(autoconnected
)信号,然后将此信号(与链接到其上的变换)合并为相同的信号(使用远程负载,链接到它的保存,加载和转换)。但是,这永远不会进入远程负载,我只能认为是由于本地负载信号发送completed
。
有什么办法可以做我想做的事吗?我的逻辑错了吗? 提前感谢任何建议。
答案 0 :(得分:0)
一种可能性是使用主题。如果您不熟悉,可以订阅主题,就像正常信号一样,但您可以明确地告诉它发送值(或错误或已完成的消息)。您还可以订阅“信号主题”,主题会将该信号的消息传播给自己的订阅者。
您可能希望以更漂亮的方式将其封装起来,但我认为以下内容可以满足您的需求:
let subject = RACSubject()
subject.map {
let localObject = $0 as! LocalObjectType
return transformLocalFormToFinalForm(localObject)
}
.subscribeNext {
let finalObject = $0 as! FinalObjectType
// Process your final object here
}
let localObjectId = ... // Assuming the ID exists
getLocalObject(localObjectId).doNext {
subject.sendNext($0)
}
.flattenMap {
let localObject = $0 as! LocalObjectType
return getRemoteObject(localObject.remoteId)
}
.flattenMap {
let remoteObject = $0 as! RemoteObjectType
return saveRemoteObjectToLocalStore(remoteObject)
}
.flattenMap {
return getLocalObject(localObjectId)
}
.subscribeNext({
subject.sendNext($0)
subject.sendCompleted()
}, error {
subject.sendError($0)
})
此设置应执行以下操作:
希望这有帮助!