【问题标题】:Swift Combine making serial sequence in orderSwift Combine按顺序制作序列
【发布时间】:2023-09-17 03:44:01
【问题描述】:

这是一个简单的游乐场代码,它以相反的顺序显示两个订阅。如何修改代码使其始终打印出 555?目前它随机打印 0 或 555,因为操作是异步的。请记住,这是一个概念,而不是要解决的实际问题,因此将所有东西放在一个水槽中并不是解决方案。谢谢

import Combine

class Foo {

    let subject = PassthroughSubject<Void, Never>()
    var myProperty = 0

    var bag = Set<AnyCancellable>()

    init() {
        subject
            .sink { _ in print(self.myProperty) }
            .store(in: &bag)

        subject
            .map { _ in 555 }
            .assign(to: \.myProperty, on: self)
            .store(in: &bag)

        subject.send()
    }
}

let testClass = Foo()

【问题讨论】:

  • 您应该修改问题以包含您要解决的问题。十年来我一直在使用功能性反应管道,而且我一次也不需要这种行为,所以我怀疑这是一个 XY 问题(你正在寻求 X 的帮助,但你真的需要Y) 的解决方案。
  • 我同意上述观点。书面问题的解决方案是与一个发布者按顺序完成工作(例如sink { print("1"); print("2"); print("3"); }),因此您要问的内容必须更多。
  • 抱歉误导,我已经修改了帖子以在此处显示更清晰的挑战
  • 您的概念不适合按照措辞结合。同一发布者的不同订阅者接收事件的顺序未定义。所以你的问题是错误的。如果您需要对事物的时间顺序,您应该重新考虑您对事件的反应方式。在此示例中,您既要存储事件,又要产生副作用(读取成员 var 并打印它,它不使用触发它的事件)。这就是你问题的根源。

标签: ios swift queue combine


【解决方案1】:

PassthroughSubject 不保证向其订阅者发送值的顺序。您不能强制执行订单,并且该订单可能会在未来的 Combine 版本中发生变化。

一种将myProperty 存储在其自己的主题中并订阅该主题以获得+555 值的解决方案:

import Combine

class Foo {
    
    let subject = PassthroughSubject<Void, Never>()
    private var _myProperty = CurrentValueSubject<Int, Never>(0)
    var myProperty: Int { _myProperty.value }
    
    var bag = Set<AnyCancellable>()
    
    init() {
        _myProperty
            .sink { _ in print(self.myProperty) }
            .store(in: &bag)
        
        subject
            .map { _ in 555 }
            .assign(to: \.value, on: _myProperty)
            .store(in: &bag)
        
        subject.send()
    }
}

let testClass = Foo()

【讨论】:

    最近更新 更多