Ios 如何压缩两个发布服务器,但获取最新的值,而不是压缩的默认最旧行为?
我需要使用Ios 如何压缩两个发布服务器,但获取最新的值,而不是压缩的默认最旧行为?,ios,swift,reactive-programming,combine,publisher,Ios,Swift,Reactive Programming,Combine,Publisher,我需要使用Swift构建一个Combine管道,其中涉及两个发布者,pubA(一个PassThroughSubject)频繁生成值,一旦pubB(另一个PassThroughSubject)生成值,我需要使用pubA的最新值触发事件。唯一严格的条件是-触发器应该只发生在pubA(驱动发布者)的新值上,管道应该从pubA获取最新发布的值(应该跳过旧值)。让我试着举例说明: pubA => 1 2
Swift
构建一个Combine
管道,其中涉及两个发布者,pubA(一个PassThroughSubject)频繁生成值,一旦pubB(另一个PassThroughSubject)生成值,我需要使用pubA的最新值触发事件。唯一严格的条件是-触发器应该只发生在pubA(驱动发布者)的新值上,管道应该从pubA获取最新发布的值(应该跳过旧值)。让我试着举例说明:
pubA =>
1
2
3
4
5
pubB => true false true
Expected Output: (true, 3) (false, 5) (true, 5)
这对于Zip
一开始似乎很好,但Zip会弹出旧值而不是最新值,即输出变为(true,1)、(false,2)。使用combineLatest
每当有来自任何发布者的值时触发事件&打破依赖关系,只触发pubB的新值,因此输出变为(true,3)、(true,4)、(true,5)、(false,5)
感谢你的指点
编辑注释:
下面是我为满足我的确切需求而编写的最终代码。我不愿意从RxSwift到Combine编写一个定制的pub sub或port
CombinelateTestFrom
。
感谢@matt指导我采取正确的方法,他回答如下:
导入联合收割机
进口基金会
让pub1=PassthroughSubject()
让pub2=PassthroughSubject()
var subscriptions=Set()
pub2.map{value in(unique:UUID(),value:value)}
.CombineTest(pub1)
.删除副本{
返回$0.0.unique==$1.0.unique
}
中的.map{(元组)
返回(tuple.0.1,tuple.1)
}
.sink{中的事件
打印(事件)
}
.store(位于:&订阅中)
pub1.发送(1)
pub1.发送(2)
pub1.发送(2)
pub1.发送(3)
pub2.send(true)
pub1.发送(4)
pub1.发送(5)
pub2.发送(错误)
pub2.send(true)
输出为:
(正确,3)(假,5)
(正确,5)在RxSwift中,您要查找的被称为
withLatestFrom
。根据《联合收割机》杂志的说法,联合收割机没有等效的,所以你可能不得不自己写。这真让人心碎!如果pubB在pubA之前发布,会发生什么?如果pubB发布了两次,但没有来自pubA的干预输出,该怎么办?@Tushar,你可以在谷歌上搜索一些解决方案。这里有一个——我没有试过,但乍一看它似乎是合理的:但你必须自己测试并决定这些答案中的任何一个是否对你有用
import Combine
import Foundation
let pub1 = PassthroughSubject<Int, Never>()
let pub2 = PassthroughSubject<Bool, Never>()
var subscriptions = Set<AnyCancellable>()
pub2.map { value in (unique: UUID(), value: value) }
.combineLatest(pub1)
.removeDuplicates {
return $0.0.unique == $1.0.unique
}
.map { (tuple) in
return (tuple.0.1, tuple.1)
}
.sink { event in
print(event)
}
.store(in: &subscriptions)
pub1.send(1)
pub1.send(2)
pub1.send(2)
pub1.send(3)
pub2.send(true)
pub1.send(4)
pub1.send(5)
pub2.send(false)
pub2.send(true)