使用Swift合并执行2个并行网络请求

jei2mxaa  于 2023-02-03  发布在  Swift
关注(0)|答案(1)|浏览(358)

我正在尝试使用两个不同的发布者从两个不同的端点加载数据,这两个发布者具有不同的返回类型。我需要在两个请求都完成时更新UI,但两个请求也可能失败,因此Zip无法完成此操作。通常我会使用DispatchGroup来完成此操作,但我还没有弄清楚如何使用合并来完成此操作。是否有方法将DispatchGroup与Combine一起使用?

let dispatchGroup: DispatchGroup = .init()
let networkQueue: DispatchQueue = .init(label: "network", cos: .userInitiated)

dispatchGroup.notify { print("work all done!" }

publisher
    .receive(on: networkQueue, options: .init(group: dispatchGroup)
    .sink { ... }
    .receiveValue { ... }
    .store(in: &cancellables)

publisher2
    .receive(on: networkQueue, options: .init(group: dispatchGroup)
    .sink { ... }
    .receiveValue { ... }
    .store(in: &cancellables)

通知会立即执行,这难道不是正确的做法吗?

nvbavucw

nvbavucw1#

您可能需要使用Publishers.CombineLatest,它将获取两个发布者并创建一个新的发布者,其结果是来自两个流的 latest 值:

Publishers.CombineLatest(publisher, publisher2)
    // Receive values on the main queue (you decide whether you want to do this)
    .receive(on: DispatchQueue.main)
    .sink(receiveCompletion: { completion in
        // Handle error / completion
        // If either stream produces an error, the error will be forwarded in here
    }, receiveValue: { value1, value2 in
        // value1 will be the value of publisher's Output type
        // value2 will be the value of pubslier2's Output type
    })
    // You only need to store this subscription - not publisher and publisher2 individually
    .store(in: &cancellables)

Publishers.CombineLatest发布器可以看作是使用DispatchGroup的等价物,在DispatchGroup中,您为启动的每个网络操作调用dispatchGroup.enter()。但是,一个关键区别是,如果任何发布器生成多个值,则CombineLatest发布器将生成多个值。对于正常的网络操作,你不需要担心这个问题,但是如果你发现自己只需要合并发布者产生的前一个或前N个值,你可以使用prefix(_:)修饰符,这将确保你永远不会收到N个以上的事件。

**编辑:**更新以修复代码中的排印错误。

相关问题