当前位置: 首页 > 知识库问答 >
问题:

等待一个可观察量完成,然后再执行另一个可观察量?

韩智明
2023-03-14

问题是

我有一个活动,它定期从API获取数据并显示收到的数据。API 使用 OAuth,因此我会收到一个临时访问令牌,该令牌在一段时间(1 小时)后过期。如果应用尝试使用过期的令牌获取数据,则显然请求将失败。在我的应用的早期迭代中,我对网络请求使用 AsyncTasks,基本上只是执行了一个新的异步任务,该任务将在调用从服务器获取数据的主异步任务之前获取新的访问令牌。这工作得很好,因为主要的AsyncTask将等到另一个完成才能执行。

我最近切换到RxJava,基本上只是用Observable替换了异步任务。问题在于,获取数据的主要可观察对象不会等待刷新访问令牌的可观察对象完成。这是我的代码,谢谢你的帮助。

法典

LiveThreadActivity.java

private Subscription subscription;
private Observable<List<CustomComment>> fetchData;

@Override
protected void onResume() {
    super.onResume();

    if (tokenExpired()) {
        auth.refreshToken();
    }

    subscription = fetchData
            .compose(bindToLifecycle())
            .retryWhen(new RetryWithDelay(5, 2000))
            .subscribe(list -> addNewComments(list), e -> handleFetchDataError(e));

}


// This method gets called in onCreate()
private void dataCollection() {
    fetchData = Observable.interval(0, REFRESH_RATE, TimeUnit.MILLISECONDS)
            .map(tick -> fetchNewComments())            // Run function every time a tick is emitted
            .retryWhen( new RetryWithDelay(2, 2000) )   // Retry twice with 2 second delay
            .subscribeOn(Schedulers.io())               // Network stuff in background thread
            .observeOn(AndroidSchedulers.mainThread()); // Other stuff on the main thread

}

Auth.java

public class Auth {
    ...

    public void refreshToken() {
        Observable.just(1)
                .map(y -> refreshAccessToken())
                .retryWhen( new RetryWithDelay(3, 2000) )
                .subscribeOn(Schedulers.io())
                .subscribe();
    }
}

共有2个答案

斜宁
2023-03-14

.flatMap() 可能就足够了,即令牌可观察.flatMap(/* 返回数据可观察 */)

卜昂熙
2023-03-14

使用反应式库需要一种新的思维方式。您必须编写代码,因为它是同步的,但请注意它是异步执行的。

您的代码只是同步执行。它同时执行两个< code>Observable。

函数< code>refreshToken()应该如下所示:

public Observable<?> refreshToken() {
    return Observable.just(1)
            .map(y -> refreshAccessToken())
            .retryWhen( new RetryWithDelay(3, 2000) )
            .subscribeOn(Schedulers.io());
}

在恢复()上:

@Override
protected void onResume() {
    super.onResume();

    Observable obs = fetchData
            .compose(bindToLifecycle())
            .retryWhen(new RetryWithDelay(5, 2000));

    if (tokenExpired()) {
        obs = obs.startWith(auth.refreshToken());
    }

    subscription = obs
            .subscribe(list -> addNewComments(list), e -> handleFetchDataError(e));

}

注意startWith()操作符。它允许依次执行一个<code>可观察的<code>(获取列表)(刷新令牌)。

 类似资料:
  • 我有这个问题,我一直在寻找,但找不到解决方案(或者也许我不能根据其他答案做出解决方案)。 我的问题是,我需要找到一种方法来等待可观察的(有自己的订户)并等待另一个可观察的(有自己的订户)完成。 场景是这样的: 奥布1- 奥布斯2 - 我主要担心的是我需要两个订阅者。在我看来,obs1 和 obs2 并行运行,但需要检查 obs1 是否以新的会话令牌完成。也许这不是RxJava的主要目的。 Obs1

  • 问题内容: TL; DR 如何转换成? 我现有的代码使用Bolts构建了一系列异步任务,并等待所有这些任务完成后再执行其他步骤。本质上,它会构建a 并返回一个列表,当Bolts站点上的示例按照列表中的 所有 任务完成时,将其标记为已完成。 __ 我正在寻找替换方法,并且我假设这种方法可以构建异步任务列表(大小未知)并将它们全部包装为一个,但是我不知道如何。 我试着看,,等…但不能去工作的,我会被建

  • 我想循环使用选中的\u复选框值 对于每个人,我想做一个POST请求 然后,当foreach中的所有POST请求都完成时,我想得到刚刚查询过的数据 问题: 我的get函数与我的post函数是分开的,所以post查询没有完成,它做get,所以结果是空的get,因为post还没有发布。 解决方案: 将观测值添加到数组中,然后将它们放在foreach末尾的forkJoin中。 我所看到的可能: 将obse

  • 在一个服务中,我有两个API调用,每个调用都返回一个可观察的,在我的组件中,我有一些条件,如果为true,我必须调用这两个函数,但我需要等待get()调用,这样我就可以使用get调用返回的参数执行post函数。如果为false,我只想用已经定义的参数调用post函数。 服务: 组成部分: 我不想重复帖子调用的代码,或者如果不可能的话,只是不要在另一个订阅()中使用订阅()。我怎么能这么做?没有异步

  • 我有一个组件订阅服务中的一个可观察对象。该方法反过来订阅另一个服务中的可观察对象。我想将一个数组从最后一个服务传递回第一个服务,然后第一个服务将该数组传递回组件。更具体地说,该组件调用其本地服务,然后调用一个数据服务,该数据服务通过http客户端访问我的数据库。http客户端正在工作,数据服务将数组返回给本地服务。本地服务接收数组,但我不知道如何将该数组作为可观察对象传递回组件。以下是简短的代码块

  • 问题内容: 我有一个带有主标签页活动的Android应用程序,并且在单个标签页内有多个活动。在我的主要活动的onCreate()中,我有一个可运行的内容,它创建了一个列表,而在各个活动中,我都使用了此列表。 在各个活动的onCreate()中,我还具有在列表上运行的Runnable。但是,我需要这些Runnable仅在主选项卡活动的Runnable完成创建列表时才运行,否则我将得到一个空列表。我正