首页 > 解决方案 > 如何从 Observable 获取多种数据类型,因为 Observable 只有一种泛型类型公认

问题描述

我们已经知道 Observable 只能有一个参数作为其泛型类型。Observable 我假设我有 2 个网络调用,它们返回 2 个数据类型:UserResponseWorkResponse. 我想逐步调用 2 个这些 API,getUser 然后 getWork。最后我订阅了它们,只得到了一种数据类型,显然那是WorkResponse因为 getWork 是上游的最后一个 API 调用Observable<WorkResponse>。但是在订阅代码块中,我想同时获得UserResponseWorkResponse。那么我该如何实现呢?

1 - 有人说我应该创建一个容器类来包含两者UserResponseWorkResponse然后我可以从订阅代码块中的容器中获取这些数据类型。

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> . 如果我们需要更多参数,我们必须创建自己的参数

标签: androidrx-javarx-java2rx-android

解决方案


您可以使用 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)
    }

(未经过任何测试而编写,您可能需要稍作调整)


推荐阅读