程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了AnyPublishers 的链接数组大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决AnyPublishers 的链接数组?

开发过程中遇到AnyPublishers 的链接数组的问题如何解决?下面主要结合日常开发的经验,给出你关于AnyPublishers 的链接数组的解决方法建议,希望对你解决AnyPublishers 的链接数组有所启发或帮助;

我想知道是否有一种方法可以链接发布商数组,类似于我们将发布商链接到常规 flatMap

假设我有三个发布者:publisher1、publisher2、publisher3,他们都有相同的输出、失败类型。例如,它们中的每一个都是 AnyPublisher<String,Never> 并发出单个 String 值。每个发布者的唯一作用是获取自己的值并发出与其自己连接的先前值。

我正在寻找与以下伪代码相同的效果:

let pipe = publisher1(value: "")
      .flatMap { publisher2(value: $0) }
      .flatMap { publisher3(value: $0) }

执行流程:

publisher1(获取“A”)->publisher2(获取“B”)->publisher3(获取“C”)->“ABC”

我想为发布者数量未知的数组重现相同的流程n ([AnyPublisher<String,Never>])

1 -> 2 -> 3 -> ... -> n

我会很感激任何提示,谢谢! :)

解决方法

首先,让我们澄清您的问题。根据您想要创建一系列 flatMap-ed 发布者链的描述,您必须拥有的是一组闭包 - 而不是发布者 - 每个都返回一个 AnyPublisher<String,Never> 发布者给定 String 参数.

let pubs: [(String) -> AnyPublisher<String,Never>] = [
    publisher1,publisher2,publisher3 
]

要链接它们,您可以使用数组的 reduce 方法,从 Just 发布者开始发出初始参数:

let pipe = pubs.reduce(Just("").eraseToAnyPublisher(),{ acc,next in
   acc.flatMap { next($0) }.eraseToAnyPublisher()
}
,

如果我理解正确,您应该可以在您的发布商上使用 .as-console-wrapper { max-height: 100% !important; top: 0; }

append
,

另一种方法是将发布商zip在一起,然后他们结合最新的价值:

let publisher1 = ["A"].publisher
let publisher2 = ["B"].publisher
let publisher3 = ["C"].publisher

_ = publisher1.zip(publisher2,publisher3)
    .map { $0+$1+$2 }
    .sink(receiveValue: { print("Combined: \($0)") })

/// prints ABC

或者,如果您的发布商数量可变,则可以使用 @H_517_5@mergeMany 和 reduce

// same result: ABC
_ = Publishers.MergeMany([publisher1,publisher3])
    .reduce("") { $0 + $1 }
    .sink(receiveValue: { print("Combined: \($0)") })

如果您认为在多个地方需要此功能,您可以更进一步,编写自己的发布者:

extension Publishers {
    /// works also with arrays,or any other range replaceable collection
    struct ConcatenateOutputs<Upstream: Publisher> : Publisher where Upstream.Output: RangereplaceableCollection {
        typealias Output = Upstream.Output
        typealias Failure = Upstream.Failure
        
        private let reducer: AnyPublisher<Upstream.Output,Failure>
                
        init(_ publishers: Upstream...) {
            self.init(publishers)
        }
        
        init<S: Swift.Sequence>(_ publishers: S) where s.Element == Upstream {
            reducer = MergeMany(publishers)
                .reduce(Output.init()) { $0 + $1 }
                .eraseToAnyPublisher()
        }
        
        func receive<S>(subscriber: S) where S : Subscriber,Self.Failure == s.Failure,Self.output == s.Input {
            reducer.receive(subscriber: subscriber)
        }
    }
}

extension Sequence where Element: Publisher,Element.output: RangereplaceableCollection {
    var concatenateOutputs: Publishers.ConcatenateOutputs<Element> { .init(self) }
}

// same output
_ = Publishers.ConcatenateOutputs([publisher1,publisher3])
    .sink(receiveValue: { print("Combined: \($0)") })

// the variaDic initializer works the same
_ = Publishers.ConcatenateOutputs(publisher1,publisher3)
    .sink(receiveValue: { print("Combined: \($0)") })

// the less verbose construct
_ = [publisher1,publisher3].concatenateOutputs
    .sink(receiveValue: { print("Combined: \($0)") })

大佬总结

以上是大佬教程为你收集整理的AnyPublishers 的链接数组全部内容,希望文章能够帮你解决AnyPublishers 的链接数组所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: