0

現在、基本的な演算子を実行していて、combineLatest 演算子の動作の違いに遭遇しました。これがバグなのか、Signal と SignalProducers のバリエーションを理解できていないのか、私にはわかりません。

let (numbersSig, numbersOb) = Signal<Int, NoError>.pipe()
let (lettersSig, lettersOb) = Signal<String, NoError>.pipe()
let signal = combineLatest(numbersSig, lettersSig)
signal.observeNext({value in print(value)})

numbersOb.sendNext(1)
lettersOb.sendNext("A")
lettersOb.sendNext("B")

プロデュース: (1, "A") (1, "B")

しかし、SignalProducers を使用して同等のコードと見なされるものを作成すると、次のようになります。

let numberProducer = SignalProducer<Int, NoError> { (observer, disposable) in
    for v in [1] { observer.sendNext(v) }
}

let letterProducer = SignalProducer<String, NoError> { (observer, disposable) in
    for v in ["A", "B", "C", "D"] { observer.sendNext(v) }
}

let combinedProducer = combineLatest(numberProducer, letterProducer)
combinedProducer.on(next: {value in print(value) }).start()

出力: (1, "D")

これが責任があると思ったので、私はobserver.sendCompleted()をSignalProducersから意図的に除外しましたが、そうではありません。私は何が欠けていますか?

4

2 に答える 2

0

NachoSoto さん、ご提案ありがとうございます。あなたが提案した別のアプローチを試しましたが、出力は変わりませんでした。この問題を Github リポジトリに投稿したところ、aromas (Brian Thomas) から以下の回答を受け取りました。

CombinedProducer で start を呼び出すと、内部の文字と数字のプロデューサーで start の呼び出しが処理されます (具体的には、SignalProducer.swift の liftRight を参照してください。otherProducer.startWithSignal のクロージャーが返されると、sendNext コードが実行されます)。それらは同期しているため、数値プロデューサーが値を返し始める前に、文字プロデューサーはすべての値を単純に「次へ」します。これをテストするには、プロデューサーの例の CombineLatest メソッド呼び出しでそれらを逆にします。最初のテストの「プッシュ値」の動作を取得したい場合は、次を試してください

let (numbersSig, numbersSink) = Signal<Int, NSError>.pipe()
let (lettersSig, lettersSink) = Signal<String, NSError>.pipe()
let numberProducer = SignalProducer(signal: numbersSig)
let letterProducer = SignalProducer(signal: lettersSig)

let combinedProducer = combineLatest(numberProducer, letterProducer)
combinedProducer.on(next: {value in print(value) }).start()

lettersSink.sendNext("A")
numbersSink.sendNext(1)
lettersSink.sendNext("B")
numbersSink.sendNext(2)
lettersSink.sendNext("C")

彼が提案したようにnumberProducerとletterProducerを逆にしてみましたが、出力は実際にシグナルを使用して最初に遭遇したものでした。

let numberProducer = SignalProducer<Int, NoError> { (observer, disposable) in
    for v in [1] { observer.sendNext(v) }
}

let letterProducer = SignalProducer<String, NoError> { (observer, disposable) in
    for v in ["A", "B", "C", "D"] { observer.sendNext(v) }
}

let combinedProducer = combineLatest(letterProducer, numberProducer)
combinedProducer.startWithNext {value in print(value)}

プロデュース: ("A", 1) ("B", 1) ("C", 1) ("D", 1)

これはまだバグまたは実装の動作だと思いますか?

于 2016-03-11T14:10:15.970 に答える
0

ええ、これはバグのようです。Github レポジトリでイシューを開いて確認していただけませんか? さらに良いことに、失敗したテストで PR を開くことができれば最高です! :)

+startWithNextの代わりに使用しても同じ結果が得られますか?onstart

于 2016-03-09T15:28:50.830 に答える