gpt4 book ai didi

swift - 如何压缩4个以上的发布者

转载 作者:行者123 更新时间:2023-12-03 09:23:36 26 4
gpt4 key购买 nike

我正在对我的API请求使用Swift Combine。现在,我面临一种情况,我想将4个以上的并行请求压缩在一起。在我有4个使用Zip4()运算符压缩在一起的请求之前。我可以想象您要分多个步骤进行压缩,但是我不知道如何为它编写receiveValue。

这是我当前代码的简化,其中包含4个并行请求:

    Publishers.Zip4(request1, request2, request3, request4)
.sink(receiveCompletion: { completion in
// completion code if all 4 requests completed
}, receiveValue: { request1Response, request2Response, request3Response, request4Response in
// do something with request1Response
// do something with request2Response
// do something with request3Response
// do something with request4Response
}
)
.store(in: &state.subscriptions)

最佳答案

不幸的是,Apple选择使zip运算符的输出成为元组,这使您无法压缩任意数量的发布者。元组非常不灵活,并且功能有限。您不能有一个由10个元素组成的元组;而且您甚至无法将元素附加到元组,因为这会导致您获得其他类型。因此,我们需要一个新的运算符,该运算符的功能与zip相同,但发出一些更强大,更灵活的结果,例如数组。

我们可以做一个!幸运的是,zip运算符本身具有transform参数,可让我们指定所需的输出类型。

好的,为了说明这一点,我将把十个发布者压缩在一起。首先,我将组成十个发布者;他们将仅仅是Just Publishers,但这足以说明问题,并证明我没有作弊,我将对每个人都施加任意延迟:

let justs = (1...10).map {
Just($0)
.delay(for: .seconds(Int.random(in:1...3)), scheduler: DispatchQueue.main)
.eraseToAnyPublisher() }

好的,现在我有了一系列的发布者,我将它们压缩成一个循环:
let result = justs.dropFirst().reduce(into: AnyPublisher(justs[0].map{[$0]})) { 
res, just in
res = res.zip(just) {
i1, i2 -> [Int] in
return i1 + [i2]
}.eraseToAnyPublisher()
}

注意 zip运算符后的结尾闭包!这样可以确保我的输出将是 Array<Int>而不是元组。与元组不同,我被允许制作任何大小的数组,每次循环都添加元素。

好的,所以 result现在是一个Zip发布者,可以将10个发布者压缩在一起。为了证明这一点,我将为其附加一个订户并打印输出:
result.sink {print($0)}.store(in: &self.storage)

我们运行代码。有一个令人心碎的暂停-正确,因为每个Just出版商都有不同的随机延迟,而zip的规则是他们都需要在获得任何输出之前进行发布。他们迟早都会这样做,并且输出将显示在控制台中:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

正确的答案!我已经证明我实际上确实将十个发布者拉在一起,以产生由每个发布者的一个贡献组成的输出。

将任意数量的数据任务发布者(或您使用的任何东西)压缩在一起并没有什么不同。

(有关一个问题,我将在其中学习如何序列化任意数量的数据任务发布者,请参阅 Combine framework serialize async operations。)

关于swift - 如何压缩4个以上的发布者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60345806/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com