有没有一种方法可以发出类似于 combineLatest 的信号,而不需要所有信号都在最初触发?
Is there a way to make a signal similar to combineLatest without needing all the signals to initially fire?
我有一组信号
var signals = [Signal<ActionResult?, NoError>]()
其中
enum ActionResult
case failed
case pending
case completed
}
我想创建一个组合信号,如果一个或多个信号触发 .pending
,则 returns 为真
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 中做到这一点?
试试这个:
let doesAnyOfTheActionsLoad = Signal.merge(signals).map { [=10=] == .pending}
如果您希望信号在一个 .pending
之后保持为真,那么您需要使用类似 scan
运算符的东西来存储当前状态:
let doesAnyOfTheActionsLoad = Signal.merge(signals).scan(false) { state, next in
if case .pending? = next {
return true
}
else {
return state
}
}
scan
就像 reduce
的 "live" 响应式版本;每次有新值进入并累积时,它都会发送当前结果。
其他解决方案在技术上是正确的,但我认为这可能更适合您的用例。
// 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 { [=10=] == .pending } // Convert every value to a bool representing whether that value is `.pending`.
.filter { [=10=] } // 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).
我有一组信号
var signals = [Signal<ActionResult?, NoError>]()
其中
enum ActionResult
case failed
case pending
case completed
}
我想创建一个组合信号,如果一个或多个信号触发 .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 中做到这一点?
试试这个:
let doesAnyOfTheActionsLoad = Signal.merge(signals).map { [=10=] == .pending}
如果您希望信号在一个 .pending
之后保持为真,那么您需要使用类似 scan
运算符的东西来存储当前状态:
let doesAnyOfTheActionsLoad = Signal.merge(signals).scan(false) { state, next in
if case .pending? = next {
return true
}
else {
return state
}
}
scan
就像 reduce
的 "live" 响应式版本;每次有新值进入并累积时,它都会发送当前结果。
其他解决方案在技术上是正确的,但我认为这可能更适合您的用例。
// 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 { [=10=] == .pending } // Convert every value to a bool representing whether that value is `.pending`.
.filter { [=10=] } // 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).