Попытка ввести значения в издателя, но получаю неупорядоченные значения

Это чрезмерное упрощение того, чего я пытаюсь достичь с помощью комбинирования.
Мне нужно ввести значение в общий издатель, если что-то случится. Здесь вы видите, что если число 2 получено картой, я использую команду send на исходном издателе, чтобы ввести число 3.
Я ожидал бы получить последовательность чисел, но вместо этого я получаю число 3 перед событием, которое вызвало это.

let pub = PassthroughSubject<Int, Never>()

let pubSharered = pub.share().eraseToAnyPublisher()

let anyCanc = pubSharered
.map { value -> Int in
        switch value {
        case 2:
            pub.send(3)
            return value
        default:
            return value
        }
}.sink { (value) in
    print("Sink: \(value)")
}

pub.send(0)
pub.send(1)
pub.send(2)
pub.send(4)

Результат: 0,1,3,2,4 я ожидал 0,1,2,3,4.
Кто-нибудь может это объяснить?


person Andrea    schedule 20.07.2020    source источник
comment
Как я видел ваш код, в случае 2: ​​вы выполнили две операции: 1-я - pub.send (3) и 2-я return 2, поэтому на выходе сначала return 3 перед возвратом 2.   -  person Ashutosh kumar Mishra    schedule 20.07.2020
comment
Если вы хотите, чтобы результат был 0,1,2,3,4, тогда есть два варианта: использовать провал для случая 2 или вы можете использовать блок отложенного кода в случае2.   -  person Ashutosh kumar Mishra    schedule 20.07.2020


Ответы (1)


Это похоже на вариант использования flatMap. Вы можете развернуть карту на Publishers.Sequence<[Int], Never> следующим образом:

let anyCanc = pubSharered
    .flatMap { value -> Publishers.Sequence<[Int], Never> in
        switch value {
        case 2:
            return [value, 3].publisher // value, plus a 3
        default:
            return [value].publisher // change nothing
        }
}.sink { (value) in
    print("Sink: \(value)")
}
person Sweeper    schedule 20.07.2020
comment
Здравствуйте, благодарю за ответ. Хотя ваш фрагмент делает свое дело, мой простой код является чрезмерным упрощением реального кода, в котором я уже использую flatMap. Проблема с этим фрагментом заключается в том, что только anyCanc будет проинформирован с номером 3. Поскольку pubShared имеет больше подписчиков вокруг фактического кода, я бы хотел, чтобы любой другой подписчик мог получить это введенное значение, сохраняя порядок последовательности. - person Andrea; 20.07.2020
comment
@Andrea А как насчет share вместо этого использовать плоское отображение издателя? - person Sweeper; 20.07.2020