您遇到的問題是因爲RxSwift buffer
操作員不像RxJS buffer
操作員那樣工作。它更像RxJS bufferWithTimeOrCount
運營商。
目前,從版本3.4.0開始,沒有等效於buffer
運算符。它的簽名會像func buffer(_ boundary: Observer<BoundaryType>) -> Observable<[E]>
這是一個有趣的問題來回答。我最終在這個答案的底部提供了一個緩衝區操作符。這裏是出了在Andre的代碼I的定義將如何寫溶液:
let trigger = button.rx.tap.debounce(0.25, scheduler: MainScheduler.instance)
let clickStream = button.rx.tap.asObservable()
.buffer(trigger)
.map { $0.count }
.map { $0 == 1 ? "click" : "\($0)x clicks" }
let clearStream = clickStream
.debounce(10.0, scheduler: MainScheduler.instance)
.map { _ in "" }
Observable.merge([clickStream, clearStream])
.bind(to: label.rx.text)
.disposed(by: bag)
上述代碼應放置在視圖控制器的viewDidLoad
方法。我做了一個大的改變和一個小的改變。這個小小的變化是我用反彈而不是油門。再一次,我認爲RxJS的油門與RxSwift的油門不同。最大的改變是我將multiClickStream和singleClickStream結合起來。我不完全確定他爲什麼做了兩個獨立的流...
我做的另一個改變是將影響標籤的所有可觀察物捲成標籤可以綁定的一個可觀察物,而不是具有不同的可觀察物。我認爲這更清潔。
下面是我定義的緩衝區操作符。
extension Observable {
/// collects elements from the source sequence until the boundary sequence fires. Then it emits the elements as an array and begins collecting again.
func buffer<U>(_ boundary: Observable<U>) -> Observable<[E]> {
return Observable<[E]>.create { observer in
var buffer: [E] = []
let lock = NSRecursiveLock()
let boundaryDisposable = boundary.subscribe { event in
lock.lock(); defer { lock.unlock() }
switch event {
case .next:
observer.onNext(buffer)
buffer = []
default:
break
}
}
let disposable = self.subscribe { event in
lock.lock(); defer { lock.unlock() }
switch event {
case .next(let element):
buffer.append(element)
case .completed:
observer.onNext(buffer)
observer.onCompleted()
case .error(let error):
observer.onError(error)
buffer = []
}
}
return Disposables.create([disposable, boundaryDisposable])
}
}
}
謝謝你的回答。如果有人提供解決方案,或者我自己想出了一些解決方案,我會讓這個問題多一點。 –
您可能會覺得這個討論很有趣:https://github.com/ReactiveX/RxSwift/issues/590 –
非常感謝您的解決方案和解釋。 –