Ios 如何使用rxSwift进行压缩、合并或压缩,而不覆盖以前的数据?
我有三个Ios 如何使用rxSwift进行压缩、合并或压缩,而不覆盖以前的数据?,ios,swift,observable,concat,rx-swift,Ios,Swift,Observable,Concat,Rx Swift,我有三个Observable流,我想把它们合并成一个Observable 如果我使用Observable.zip(早餐、甜点、饼干).do(onNext:{[weak self]value in… 我得到([Recipe],[Recipe],[Recipe]) 如果我使用Observable.merge(早餐、甜点、饼干).do(onNext:{[weak self]value in… 我依次获得流,这意味着最后一个完成的流将覆盖前两个 如果我使用Observable.concat(早餐、甜点、
Observable
流,我想把它们合并成一个Observable
如果我使用Observable.zip(早餐、甜点、饼干).do(onNext:{[weak self]value in…
我得到([Recipe],[Recipe],[Recipe])
如果我使用Observable.merge(早餐、甜点、饼干).do(onNext:{[weak self]value in…
我依次获得流,这意味着最后一个完成的流将覆盖前两个
如果我使用Observable.concat(早餐、甜点、饼干).do(onNext:{[weak self]value in…
我的行为与merge
类似
那么,如何将这三个流合并为一个流,而不让它们相互覆盖呢
为了更好地了解我要做的事情:
return Observable.merge(breakfast, cookies, dessert).do(onNext: { [weak self] value in
self?.content.accept(value.compactMap { FavoritesCollectionViewCellViewModel(favorite: $0)})
})
我想
接受所有组合流到行为关系
,映射到单元格
数据。内容
中继随后被绑定到集合视图
。当观看集合视图
时,使用concat
我可以简单地看到第一个和第二个流,然后它们被重新播放与最后一个流进行了比较。好的,我不知道这是否是解决问题的最漂亮的方法,但我使用了zip
,然后在compactMap
中将数组相互添加
return Observable.zip(breakfast, dessert, cookies)
.compactMap { $0.0 + $0.1 + $0.2 }
.do(onNext: { [weak self] value in
self?.content.accept(value.compactMap { FavoritesCollectionViewCellViewModel(favorite: $0)})
})
您可能不知道,但是CombineTest(和zip)有一个用于操作输入的最终参数。因此,您可以执行以下操作:
let allRecipes = Observable.combineLatest(breakfast, dessert, cookies) { $0 + $1 + $2 }
这相当于:
Observable.combineLatest(breakfast, dessert, cookies)
.map { $0.0 + $0.1 + $0.2 }
这与您最终得到的基本相同,只是您使用了zip
而不是combinelateest
使用zip
假设所有三个可观测对象将发射完全相同数量的元素。通过使用CombineTest,您假设每个可观测对象至少发射一个元素,但它们不必发射相同数量的元素
如果您想避免这种假设,那么在每个源代码中添加一个.startWith
Observable.combineLatest(
breakfast.startWith([]),
dessert.startWith([]),
cookies.startWith([])
) { $0 + $1 + $2 }
通过上面的方法,只要有一个可观测的源发射,你就会在输出中得到一些东西,而其他源每次发射时,你就会得到另一个更大的阵列
请注意,在以上所有内容中(包括您的答案)任何一个源观测值中的错误都会导致整个事件出错。如果要避免这种情况,您必须捕获每个源观测值中的错误。该代码的确切外观取决于您希望如何处理这些错误。这是一个非常好的解释,非常感谢@Daniel T。
Observable.combineLatest(
breakfast.startWith([]),
dessert.startWith([]),
cookies.startWith([])
) { $0 + $1 + $2 }