有没有办法制作一个与CombineLatest相似的信号,而无需所有信号来最初发射



我有一系列信号

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

其中

enum ActionResult
    case failed
    case pending
    case completed
}

我想创建一个组合信号,如果一个或多个信号发射 .pending

,则返回true
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
     })
}

我唯一的问题是,CombinAtest只有在所有信号至少发射一次时才会触发,而我需要信号发射,无论是否所有信号都发射。有没有办法在ReactiveSwift?

尝试以下:

 let doesAnyOfTheActionsLoad = Signal.merge(signals).map { $0 == .pending}

如果您希望信号在一个.pending之后保持真实,则需要将当前状态存储在scan操作员之类的地方:

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

scan就像 reduce的"实时"反应性版本;每当新值进来并累积时,它都会按照当前的结果发送。

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

// 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).

相关内容

  • 没有找到相关文章

最新更新