【问题标题】:Swift Combine: How do I merge the results from several nested Publishers?Swift Combine:如何合并来自多个嵌套发布者的结果?
【发布时间】:2021-08-28 07:30:00
【问题描述】:

我正在编写一些代码并尝试使用 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)
}

但我仍在努力让这一切编译和工作。

有没有人尝试过这样的事情?你是如何将发布者的结果合并到多个对象中的?

【问题讨论】:

    标签: swift combine


    【解决方案1】:

    您可以在数组上执行reduce,每个部分结果由appending 数组中的发布者计算。然后,使用collect 获取Publisher&lt;[String], Error&gt;

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-10
      • 1970-01-01
      • 1970-01-01
      • 2020-08-05
      • 2019-11-08
      • 2018-02-26
      • 1970-01-01
      • 2020-11-06
      相关资源
      最近更新 更多