我有一系列设备,我想尝试连接到其中一个设备,如果成功停止尝试连接到其他设备并返回 onCompleted,如果连接到设备失败,请尝试阵列中的下一个设备,等等。
Observable.from(devices)
.enumerated()
.flatMap { itemIndex, item -> Completable in
return service.connectTo(device: item).catchError({ error in
if itemIndex == devices.count - 1 {
return Completable.error(error)
}
return Completable.empty()
})
}
.subscribe(onError: { error in
// Do something with error
}, onCompleted: {
// Do something on completed
}).disposed(by: bag)
我尝试在 connectTo(device: item) 之后添加 onCompleted,但这会在一切完成后被调用。
对,因为
flatMap
在它订阅的每个可观察对象完成之前不会完成。对于这个用例amb
可能是正确的选择。
amb
的工作方式是它订阅一个序列中的所有可观察对象。一旦一个发出一个值,所有其余的都被取消。
protocol Service {
func connectTo(device: Device) -> Completable
}
struct Device { }
func example(service: Service, devices: [Device], bag: DisposeBag) {
Observable.amb(devices.map { service.connectTo(device: $0).andThen(.just($0)) })
.subscribe(
onNext: { device in
// this gives the device that was connected to
// do something with it
},
onError: { error in
// Do something with error
}
)
.disposed(by: bag)
}
上面的代码假定
connectTo(device:)
方法返回一个Completable。如果它返回一个Observable<Void>
,事情就会简单一些。一般来说,我建议使用Observable<Void>
而不是Completable
。