簡體   English   中英

我如何觀察信號並立即收到“ next”事件(如果已經發生)?

[英]How do I observe a signal and immediately receive a `next` event if it has already occured?

我正在嘗試包裝網絡請求后初始化對象的API調用。 我不希望每個新觀察者都發生網絡請求,因此據我了解,我不應該使用SignalProducer 但是,通過使用單個Signal ,只有它的第一次使用會收到next事件,而任何新訂閱者將永遠不會收到當前值。 我應該怎么做? 我可能在做RAC根本上出錯的事情。

extension SparkDevice {
    static func createMainDeviceSignal() -> Signal<SparkDevice, NSError> {
        return Signal {
            sink in
            SparkCloud.sharedInstance().getDevices { (sparkDevices: [AnyObject]!, error: NSError!) -> Void in
                if let error = error {
                    sink.sendFailed(error)
                }
                else {
                    if let devices = sparkDevices as? [SparkDevice] {
                        if devices.count > 0 {
                            sink.sendNext(devices[0])
                        }
                    }
                }
            }
            return nil
        }
    }
}

class DeviceAccess {
    let deviceSignal: Signal<SparkDevice, NSError>

    init() {
        self.deviceSignal = SparkDevice.createMainDeviceSignal()
    }
 }

我考慮過使用MutableProperty ,但這似乎需要一個默認屬性,這似乎沒有任何意義。

我實際上應該如何處理?

您需要的是多播 但是, ReactiveCocoa 3/4並沒有提供一種簡單的方法(與Rx相對),因為它們通常會導致大量的復雜性。

有時確實很必要,如您的示例所示,並且可以使用PropertyType輕松實現。

我將從創建發出請求的冷信號開始。 那必須是SignalProducer

private func createMainDeviceSignalProducer() -> SignalProducer<SparkDevice, NSError> {
    return SignalProducer { observer, _ in
        ....
    }
}

如果你要原樣公開此,副作用會發生每到這個制片人是時候start編輯。 multicast這些值,您可以將其包裝在屬性中,然后公開該propertyproducer

public final class DeviceAccess {
    public let deviceProducer: SignalProducer<SparkDevice, NoError>
    private let deviceProperty: AnyProperty<SparkDevice?>

    init() {
        self.deviceProperty = AnyProperty(
           initialValue: nil, // we can use `nil` to mean "value isn't ready yet"         
           producer: SparkDevice.createMainDeviceSignal()
                        .map(Optional.init) // we need to wrap values into `Optional` because that's the type of the property
                        .flatMapError { error in 
                              fatalError("Error... \(error)") // you'd probably want better error handling

                              return .empty // ignoring errors, but you probably want something better.
                        }
        )

        self.deviceProducer = deviceProperty
              .producer    // get the property producer
              .ignoreNil() // ignore the initial value
    }
 }

現在, DeviceAccess.deviceProducer將重播底層生產者發出的值,而不是重復產生副作用。 但是請注意,這並不懶惰 :底層的SignalProducer將立即啟動。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM