简体   繁体   English

Swift Combine:在未调用序列发布者之后收集

[英]Swift Combine: collect after sequence publisher not called

I have a subject which sends/receives an array of Data like PassthroughSubject<[Int], Never>() .我有一个发送/接收数据数组的主题,如PassthroughSubject<[Int], Never>() When a value is received I want to split the array in single values to manipulate them and afterwards collect them again.当收到一个值时,我想将数组拆分为单个值来操作它们,然后再次收集它们。

I know that the issue is that the flatMap never sends the completion Event.我知道问题是flatMap从不发送完成事件。 But how can I solves this issue?但是我该如何解决这个问题呢? Or is there a better way to manipulate every value in an array with combine?或者有没有更好的方法来操作数组中的每个值?

Edit: I don't want to complete the subject to collect.编辑:我不想完成要收集的主题。 I want to collect the output of the sequencer.我想收集音序器的输出。

Example:例子:

import Combine

var storage = Set<AnyCancellable>()
let subject = PassthroughSubject<[Int], Never>()

subject
    .flatMap { $0.publisher }
    .map { $0 * 10 }
    .collect()
    .sink {
        print($0) // Never called
    }
    .store(in: &storage)

subject.send([1, 2, 3, 4, 5])

I found a solution how I achieved the my expected outcome.我找到了如何实现预期结果的解决方案。 I had to move the map and collect within the flatMap .我不得不移动map并在flatMap collect

import Combine

var storage = Set<AnyCancellable>()
let subject = PassthroughSubject<[Int], Never>()

subject
    .flatMap { $0.publisher
        .map { $0 * 10 }
        .collect()
    }
    .sink {
        print($0)
    }
    .store(in: &storage)

subject.send([1, 2, 3, 4, 5])
subject.send([1, 2, 3, 4, 5].reversed())

This will print [10, 20, 30, 40, 50] and [50, 40, 30, 20, 10] .这将打印[10, 20, 30, 40, 50][50, 40, 30, 20, 10]

collect waits for the publisher to complete. collect等待发布者完成。 A PassthroughSubject doesn't automatically complete. PassthroughSubject不会自动完成。 You need to call send(completion: on it.你需要调用send(completion: on it。

subject.send([1, 2, 3, 4, 5])
subject.send(completion: .finished) // now `sink` will be triggered

You don't need the flatMap() and the collect() calls, you can simply map() over the received array:你不需要flatMap()collect()调用,你可以简单地map()在接收到的数组上:

subject
    .map { $0.map { $0 * 10 } }
    .sink {
        print($0) // Now it's called :)
    }
    .store(in: &storage)

subject.send([1, 2, 3, 4, 5])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM