英文:
How to handle success case and failure case for multiple API calls when using Observable zip in RxSwift
问题
我使用Observable.zip()
调用了两个独立的API。在这种情况下,如果第一个API失败(返回某种错误),即使第二个API成功,也不会在subscribe(onNext)
闭包内执行,反之亦然。我仍希望从每个API调用中获取成功和失败的情况。<br>如何使用Observable zip解决这个问题,或者我应该使用其他方法来实现这一点?
Observable.zip(api1(), api2())
.subscribe { [weak self] in
print($1) // 如果第一个API调用失败,这里不会打印任何内容。
}
.onError: {
print("error", $0)
}
.disponseBag(by: disposebag)
英文:
I call two independent API calls using Obeservable.zip(). In this case, if the first API fails(returning some kind of error), the second API never executes inside the subscribe(onNext) closure even if it is successful. and vice versa. I still want the success case and failure case from each api call. <br> How can I solve this issue using Observable zip or should I use another method to achieve this?
Observable.zip(api1(), api2())
.subscribe { [weak self] in
print($1) //if the first api call fails, Nothing prints out here.
}
.onError: {
print("error", $0)
}
.disponseBag(by: disposebag)
答案1
得分: 0
不只是第一个失败的情况。如果任何一个 Observable 失败,另一个将被处理,你的 onNext 将不会被调用。
有几种不同的方法可以解决这个问题,它们都涉及将 error
事件转换为 next
事件。
你可以使用:
Observable.zip(api1.materialize(), api2.materialize())
.subscribe(
onNext: { lhs, rhs in
switch (lhs, rhs) {
case let (.next(left), .next(right)):
print(left, right)
case let (.error(left), .next(right)):
print(left, right)
case let (.next(left), .error(right)):
print(left, right)
case let (.error(left), .error(right)):
print(left, right)
default:
return
}
},
onError: { _ in /*不会被调用*/ })
或者如果你不关心错误,你可以将它们转换为 Optionals:
Observable.zip(
api1.map(Optional.some).catch { _ in .just(nil) },
api2.map(Optional.some).catch { _ in .just(nil) }
)
.subscribe(
onNext: { lhs, rhs in
print(lhs as Any, rhs as Any) // 错误将为 `nil`
},
onError: { _ in /*不会被调用*/ })
如果你不需要两个网络调用的结果来进行工作,那么另一个选择是保持两个请求分开:
api1
.subscribe(onNext: { print($0) }, onError: { print($0) })
api2
.subscribe(onNext: { print($0) }, onError: { print($0) })
英文:
It's not just if the first fails. If either Observable fails, the other will be disposed and your onNext will not be called.
There are a few different ways to solve this, and they all involve turning the error
event into a next
event.
You could use:
Observable.zip(api1.materialize(), api2.materialize())
.subscribe(
onNext: { lhs, rhs in
switch (lhs, rhs) {
case let (.next(left), .next(right)):
print(left, right)
case let (.error(left), .next(right)):
print(left, right)
case let (.next(left), .error(right)):
print(left, right)
case let (.error(left), .error(right)):
print(left, right)
default:
return
}
},
onError: { _ in /*will not get called*/ })
or you if you don't care about the errors, you could convert them to Optionals:
Observable.zip(
api1.map(Optional.some).catch { _ in .just(nil) },
api2.map(Optional.some).catch { _ in .just(nil) }
)
.subscribe(
onNext: { lhs, rhs in
print(lhs as Any, rhs as Any) // errors will be `nil`
},
onError: { _ in /*will not get called*/ })
If you don't need the results of both network calls to do work, then another option would be to just keep the two requests separate:
api1
.subscribe(onNext: { print($0) }, onError: { print($0) })
api2
.subscribe(onNext: { print($0) }, onError: { print($0) })
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论