1

我有两个Action具有相同输入/输出/错误类型的 s,我想将它们组合成一个Action运行两者中的任何一个启用的单个(如果它们都启用,则使用任意决胜局)。

这是我的第一个失败的尝试:

let addOrRemove: Action<MyInput, MyOutput, APIRequestError> = Action(enabledIf: add.isEnabled.or(remove.isEnabled)) { input in
    if add.isEnabled.value {
        return add.apply(input)
    } else {
        return remove.apply(input)
    }
}

这失败了,因为内部add.apply(input)看不到 I checked ,所以它在错误类型周围add.isEnabled包裹了一个额外的层。ActionError<>(这可能是合法的,因为我不确定这种方法的线程安全性如何,或者可能是我们知道类型系统不知道的东西。)相应的类型错误是:

cannot convert return expression of type 'SignalProducer<MyOutput, ActionError<APIRequestError>>' to return type 'SignalProducer<MyOutput, APIRequestError>'

我应该怎么做?

4

1 回答 1

1

Github user @ikesyo provided the following answer on the ReactiveSwift issue I opened to ask the same question:

let producer: SignalProducer<MyOutput, ActionError<APIRequestError>>
if add.isEnabled.value {
    producer = add.apply(input)
} else {
    producer = remove.apply(input)
}
return producer.flatMapError { error in
    switch error {
    case .disabled: return .empty
    case let .producerFailed(inner): return SignalProducer(error: inner)
    }
}

If they show up here I'll happily change the accepted answer to theirs (credit where it belongs).

Warning: If I'm reading this answer correctly, it's not watertight. If add changes from enabled to disabled between the apply() and the start() of the wrapping Action, we'll get "success" (no values, but .completed) instead of the .disabled we should get. That's good enough for my use case, but YMMV.

于 2017-05-11T06:31:11.167 回答