1

関数multiply()convert()(概念の最小限の例、実際には各関数内のリモートサーバーにクエリを実行することを計画しています)、実装するより短い方法は何multiplyAndConvert()ですか?

// call two async functions passing the result the from the first 
// as the argument to the second
multiplyAndConvert(3).startWithResult { val in
    print("\(val.value!)")
}

func convert(_ val: Int) -> SignalProducer<String, NSError> {
    return SignalProducer<String, NSError> { observer, _ in
        observer.send(value: String(val))
        observer.sendCompleted()
    }
}

func multiply(_ val: Int) -> SignalProducer<Int, NSError> {
    return SignalProducer<Int,NSError> { observer, _ in
        observer.send(value: val * 2)
        observer.sendCompleted()
    }
}

func multiplyAndConvert(_ val: Int) -> SignalProducer<String, NSError> {
    return SignalProducer<String, NSError> { observer, _ in
        multiply(val).startWithResult { res2 in
            switch res2 {
                case .success(let val2):
                    convert(val2).startWithResult { res3 in
                        switch res3 {
                            case .success(let val3):
                                observer.send(value:val3)
                                observer.sendCompleted()
                            case .failure(let err):
                                observer.send(error:err)
                        }
                    }
                case .failure(let err):
                    observer.send(error: err)
            }
            observer.sendCompleted()
        }
    }
}

これを行うにはもっとエレガントな方法が必要であることは知っていますが、それが何であるかについては困惑しています。map、flatMap、flatten、およびその他のほとんどの関数をいじってみましたが、より良い解決策が見つかりません。

4

1 に答える 1

3

flatMap を使用します。

func multiplyAndConvert(_ val: Int) -> SignalProducer<String, NSError> {
  return multiply(val).flatMap(.concat) { multipliedVal in
    return convert(multipliedVal)
  }
}

convertクロージャーを与えるのではなく、flatMap の 2 番目の引数として直接渡すこともできますInt -> SignalProducer<String, NSError>

multiply(val).flatMap(.concat, transform: convert)

ただし、展開されたコードでconvert関数が参照selfする場合、保持サイクルが発生する可能性があります。その場合、クロージャをキャプチャするパスが必要になります。[weak self]

説明

ここで何をするかflatMapは、乗算信号を取ります:

-----.value(multipliedValue)-.completed

提供されたクロージャーを使用して、シグナルオブシグナルにマップします。

    .value(convertedMultipliedValue)
    /
----x-.completed

次に、この信号の信号を「平坦化」します (すべての子信号を連結することによって信号の信号を平坦化する .Concat 平坦化戦略を使用しますが、単一の子信号のみを平坦化するため、ここでは問題になりません)。私たちに与えるために:

----.value(convertedMultipliedValue)-.completed
于 2016-10-13T22:32:07.277 に答える