3

我有一系列信号

var signals = [Signal<ActionResult?, NoError>]()

在哪里

enum ActionResult
    case failed
    case pending
    case completed
}

我想创建一个组合信号,如果一个或多个信号触发一个返回 true.pending

let doesAnyOfTheActionsLoad = Signal.combineLatest(signals).map { values in

     values.reduce(false, { (result, nextResult) -> Bool in
         if result == true { return true }

             if case .pending? = nextResult {
                 return true
             }
         return false
     })
}

我唯一的问题是,combineLatest 只有在所有信号都至少触发一次时才会触发,并且无论是否所有信号都已触发,我都需要我的信号触发。有没有办法在 ReactiveSwift 中做到这一点?

4

3 回答 3

3

尝试这个:

 let doesAnyOfTheActionsLoad = Signal.merge(signals).map { $0 == .pending}
于 2018-02-15T10:47:43.983 回答
3

如果您希望信号在 1 之后保持为真.pending,那么您需要使用类似scan操作符的内容存储当前状态:

let doesAnyOfTheActionsLoad = Signal.merge(signals).scan(false) { state, next in
    if case .pending? = next {
        return true
    }
    else {
        return state
    }
}

scan就像 ; 的“现场”反应式reduce版本 每次有新值进入并累积时,它都会发送当前结果。

于 2018-02-15T13:25:39.517 回答
2

其他解决方案在技术上是正确的,但我认为这可能更适合您的用例。

// Only ever produces either a single `true` or a single `false`.
let doesAnyOfTheActionsLoad = 
    SignalProducer<Bool, NoError>
        .init(signals)
        .flatten(.merge) // Merge the signals together into a single signal.
        .skipNil() // Discard `nil` values.
        .map { $0 == .pending } // Convert every value to a bool representing whether that value is `.pending`.
        .filter { $0 } // Filter out `false`.
        .concat(value: false) // If all signals complete without going to `.pending`, send a `false`.
        .take(first: 1) // Only take one value (so we avoid the concatted value in the case that something loads).
于 2018-02-15T23:15:59.480 回答