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

使用平面地图:

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

您也可以convert直接将第二个参数作为第二个参数传递给 flatMap 而不是给它一个闭包,因为它已经是正确的类型 ( 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 回答