我正在编写一些代码,并试图使用Combine来简化流程。到目前为止,我有一个对象列表,每个对象都有一个属性,返回一个Publisher
。对象遵循协议,我尝试这样做:
protocol StringPublisher {
var stringValues: AnyPublisher<String, Error> { get }
}
let objArray:[StringPublisher] = [StringPublisher1("a","b","c"), StringPublisher2("x","y","z")]
let results: [String] = objArray.?
所以我要做的是按顺序读取objArray
实例,获得每个stringValues
发布者并处理它产生的值,直到它完成,然后侦听下一个的值,直到它完成等等。因此,上面将给出:
a
b
c
x
y
z
我想我需要这样做:
let results:[String] = objArray.flatMap(maxPublishers: .max(1)) { $0.stringValues }.sink { value in
print(value)
}
但我仍在努力让这一切编译和工作。
有人尝试过这样的东西吗?你是如何将来自发布者的结果合并到多个对象中的?
您可以对数组执行reduce
操作,通过对数组中的发布者进行append
计算每个部分结果。然后,使用collect
获得Publisher<[String], Error>
。
let stringArrayPublisher = objArray.reduce(Empty().eraseToAnyPublisher()) {
result, pub in result.append(pub.stringValues).eraseToAnyPublisher()
}.collect()
stringArrayPublisher.sink { completion in
print(completion)
} receiveValue: { value in
print("published (value)")
}
例如,如果你有
class ExampleStringPublisher: StringPublisher {
var stringValues: AnyPublisher<String, Error>
init(_ strings: String...) {
stringValues = strings.publisher.setFailureType(to: Error.self).eraseToAnyPublisher()
}
}
let objArray:[StringPublisher] = [ExampleStringPublisher("a","b","c"), ExampleStringPublisher("x","y","z")]
输出将是:
published ["a", "b", "c", "x", "y", "z"]
finished