我正在尝试将固件上传到BLE设备。因此,我推送一些数据,等待确认,然后推送更多,依此类推。 但我正在努力重复观察者直到观察者返回完成。
这是观察者,所以如果没有更多的数据包要发送,它应该完成并停止重复。
let transferImage = Observable<Void>.create { (obs) -> Disposable in
guard let nextPacket = dataSendingTracker.getNextPacket() else {
obs.onCompleted()
return Disposables.create()
}
return self.instrument()
.flatMap{ $0.sendFWpacket(packet: nextPacket) }
.subscribe(onNext: { () in
obs.onNext(())
}, onError: { (error) in
obs.onError(error)
})
}
关于如何实现这一目标的任何建议?
答案 0 :(得分:0)
尝试这样的事情,但我认为这种丑陋的方式......不是Rx解决方案
transferImage.takeWhile将在getNextPacket返回nil或此情况下整数小于零时停止。
func test() {
let transferImage = Observable<Int>.create { (obs) -> Disposable in
if let nextPacket = self.getNextPacket() {
obs.onNext(nextPacket)
} else{
obs.onNext(-1)
obs.onCompleted()
}
return Disposables.create()
}
transferImage.takeWhile{$0 > 0}.subscribe(onNext: { nextPacket in
print(nextPacket)
let completed = self.sendFWpacket()
if !completed {
self.test()
}
}, onError: { error in
print(error)
}, onCompleted: {
print("onCompleted")
}) {
print("disposed")
}.disposed(by: disposeBag)
}
func sendFWpacket()-> Bool {
return false
}
func getNextPacket() -> Int? {
return 1
}
答案 1 :(得分:0)
假设你有一个写一个数据块的函数,比如这个测试函数:
func writeDataBlock(offset: Int, blockSize: Int) -> Observable<Int> {
let writtenBytesCount = min(Int(arc4random_uniform(5) + 5), blockSize)
return Observable<Int>.just(writtenBytesCount)
}
实际上,这个函数也会使用一些数据缓冲区,并尝试在给定的偏移处从该数据中推送给定大小的块,并返回完成时写入的字节数。在这里,您可以使用transferImage
中的逻辑。
然后可以使用递归来编写完整的传递函数,如下所示:
func writeAllDataRec(offset: Int, totalSize: Int, observer: AnyObserver<String>) {
guard offset < totalSize else {
observer.onNext("writeAllData completed")
observer.onCompleted()
return
}
var subscriber: Disposable?
let blockSize = min(10, totalSize - offset)
subscriber = writeDataBlock(offset: offset, blockSize: blockSize).subscribe { ev in
switch ev {
case let .next(writtenBytesCount):
debugPrint("writeNextBlock from offset: \(offset); writtenBytesCount = \(writtenBytesCount)")
let newOffset = offset + writtenBytesCount
writeAllDataRec(offset: newOffset, totalSize: totalSize, observer: observer)
case .completed:
subscriber?.dispose()
//debugPrint("writeAllData block completed")
case let .error(err):
subscriber?.dispose()
observer.onError(err)
observer.onCompleted()
}
}
}
func writeAllData(totalSize: Int) -> Observable<String> {
return Observable<String>.create { (observer) -> Disposable in
writeAllDataRec(offset: 0, totalSize: totalSize, observer: observer)
return Disposables.create()
}
}
可以这样测试:
var subscriber: Disposable?
...
self.subscriber = writeAllData(totalSize: 100).subscribe(onNext: { (message) in
print("\(message)")
})
在这个解决方案中,我假设您的下一个数据块取决于先前写入了多少数据,并且没有共享的全局状态。
这可以用RxJS expand的逻辑简化很多,但不幸的是这个函数在RxSwift(4.1.2)中不存在。