android - 如何从 Observable 获取多种数据类型,因为 Observable 只有一种泛型类型公认
问题描述
我们已经知道 Observable 只能有一个参数作为其泛型类型。Observable 我假设我有 2 个网络调用,它们返回 2 个数据类型:UserResponse
和WorkResponse
. 我想逐步调用 2 个这些 API,getUser 然后 getWork。最后我订阅了它们,只得到了一种数据类型,显然那是WorkResponse
因为 getWork 是上游的最后一个 API 调用Observable<WorkResponse>
。但是在订阅代码块中,我想同时获得UserResponse
和WorkResponse
。那么我该如何实现呢?
1 - 有人说我应该创建一个容器类来包含两者UserResponse
,WorkResponse
然后我可以从订阅代码块中的容器中获取这些数据类型。
2 - 创建一个临时变量来保存 userResponse 然后从 subscibe 代码块访问它,如下所示:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var tempUserResponse: UserResponse? = null
Observable.just("Prepare call API")
.flatMap {
apiGetUser()
}.flatMap { userResponse ->
tempUserResponse = userResponse // Save temporarily userResponse to pass it to subscribe code block
apiGetWork()
}.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { workResponse ->
Log.e("TAG", "userResponse = " + tempUserResponse)
Log.e("TAG", "workResponse = " + workResponse)
}
}
private fun apiGetUser(): Observable<UserResponse> {
// Fake API to get User
return Observable.just(UserResponse())
}
private fun apiGetWork(): Observable<Work> {
// Fake API to get Work
return Observable.just(Work())
}
class Work
class UserResponse
}
3 - 还有其他方法吗?请给我答案,非常感谢!
编辑:感谢您的所有回答,伙计们!你所有的答案,可能在实现方式(使用nested flatMap
或使用zip
)上有所不同,但我们都需要使用第三类作为我们需要的所有对象的容器类。内置容器类,我们有:Pair<A, B>
和Triple<A, B, C>
. 如果我们需要更多参数,我们必须创建自己的参数
解决方案
您可以使用 zip 从 2 个结果中获取一个对象:
public class MergedObject{
private Work workResponse;
private UserResponse userResponse;
MergedObject(final Work workResponse, final UserResponse userResponse){
this.workResponse= workResponse;
this.userResponse= userResponse;
}
// getter / setter
}
接着
Observable.just("Prepare call API")
.flatMap {
apiGetUser()
}.zipWith(apiGetWork(), ( userResponse, workResponse ) ->
return new MergedObject(workResponse, userResponse)
).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { mergedObject->
Log.e("TAG", "userResponse = " + mergedObject.userResponse)
Log.e("TAG", "workResponse = " + mergedObject.workResponse)
}
(未经过任何测试而编写,您可能需要稍作调整)
推荐阅读
- c# - 将平面字典序列化为多子对象 JSON
- azure - SignalR(天蓝色)。确定用户断开连接的原因
- c++ - gtkmm 键盘事件跳过
- python - 在python中将实例类型更改为继承
- python - 将数据框转换为字典
- python-3.x - Python3 - 将 unicode 文字字符串转换为 unicode 字符串
- python - 如何在需要时避免“if”嵌套python中的多个返回值
- spring-boot - 授权-Spring boot:RestTemplate + ApacheClient + JWT
- ajax - 我无法在 AJAX 使用 laravel 恢复的两个表中显示数据表中的数据
- c - 为什么即使我将其作为参数提供,gcc 也无法识别我的 .c 文件?