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

RxJava 2-在另一个Completable之后调用Completable

杜晨朗
2023-03-14

我是RxJava的新手,面临以下问题:

我有两个可完成的对象来存储一些数据。我想触发第一个,然后在第一个成功完成后再启动第二个。应该阻止对第二个Completable的调用,直到第一个完成并成功为止。此外,如果第一个完成时出现错误,则还应跳过另一个。

通过查看留档和其他SO问题,concatToandAnd似乎对我有用。但是在手动测试和单元测试中,我可以看到第二个可完成项是与第一个并行触发的:/

首先完成

public Completable doA() {
  Log.d(TAG, "class call");

  return db.countRows()
    .doOnSuccess(integer -> {
      Log.d(TAG, "found rows: "+integer);
    })
    .doOnError(Throwable::printStackTrace)
    .flatMapCompletable(this::customAction);
}

private Completable customAction(final int count) {
  Log.d(TAG, "count: "+count);
  if (count > 0) {
    Log.d(TAG, "no rows, skip");
    return Completable.complete();
  }

  final User user = ...
  return db.save(user); // return Completable
}

第二个可完成

public Completable doB() {
  Log.d(TAG, "call to B");
  // ...
}

尝试在A之后调用B

public Completable someMethod() {
    Log.d(TAG, "someMethod");
    return doA()
        .andThen(doB());
        // this also doesn't work
        //.concatWith(doB());
}

订阅

someMethod()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .doOnComplete(() -> {
      Log.d(TAG, "complete");
      // ...
    })
    .doOnError(throwable -> {
      Log.d("Main", "error "+throwable.getMessage());
      // ...
    })
    .subscribe();

当我运行应用程序并查看日志时,我可以看到:

D/Some method: some method
D/DoA: class call
D/DoB: class call   // <- why here?
D/DoA: found rows: 0
D/DoA: count: 0

此外,以下单元测试失败:

@Test
public void test() {
  when(doa.doA()).thenReturn(Completable.error(new Exception("test")));

  observe(); // subscription with TestObserver

  verify(dob, never()).doB(); // fails with NeverWantedButInvoked
}

我错过了什么?

共有2个答案

黄骏喆
2023-03-14

您可以使用andAnd()或concatBy()运算符。

返回一个Completable,该Completable首先运行此Completable,然后运行另一个Completable。

然后()

firstCompletable
    .andThen(secondCompletable)

通常,此操作符是Completable上平面图的“替换”:

Completable       andThen(CompletableSource next)
<T> Maybe<T>      andThen(MaybeSource<T> next)
<T> Observable<T> andThen(ObservableSource<T> next)
<T> Flowable<T>   andThen(Publisher<T> next)
<T> Single<T>     andThen(SingleSource<T> next)

连接方式:

firstCompletable
        .concatWith(secondCompletable)
巴星华
2023-03-14

因为您调用了doB()。让我重写您的流程:

public Completable someMethod() {
    Log.d(TAG, "someMethod");

    // doA() inlined
    LOG.d("class call");
    Completable a = ...

    // doB() inlined
    Log.d("class call");
    Completable b = ...

    return a.andThen(b);
}
 类似资料:
  • 问题内容: 我有两个完成。我想做以下情形:如果第一个Completable到达onComplete,则继续第二个Completable。最终结果将是第二完成的onComplete。 当我有单个 getUserIdAlreadySavedInDevice() 和Completable login() 时,这就是我的方法: 问题答案: 您正在寻找运营商。 返回一个Completable,它首先运行此C

  • 我尽力描述我的处境。我的wicket站点包含list wicket组件,其中每个列表元素都有另一个列表。最低级别列表中的每个元素都有下载某个文件的ajax wicket链接。这一切都很好。我习惯了这种懒散的行为。此行为的方法startDownload在link onClick方法中调用。

  • 问题内容: 我有2个差异函数中的2个ajax调用。我想使用.click调用这两个函数。func1将数据插入到数据库中,然后func2将检索数据,所以我的问题是如何等到func1完全完成后才执行func2。 我尝试了.delay(),它可以工作,但是我认为这是一个愚蠢的解决方案。 问题答案: 三种方式: 成功调用func1时调用func2: 时髦完成后,使用API调用func2: 使func1同步(

  • 问题内容: 这有道理吗? 假设我需要从数据库中获取一个与另一个对象有关系的对象(由数据库中的外键以及域对象中的组合表示)。如果在我的第一个DAO中,我获取对象1的数据,则调用对象2的dao,最后(从第一个DAO中,调用对象1中的setter,并为其提供先前获取的对象2)。 我知道我可以代替加入连接,但是对我来说,断开功能耦合似乎更合乎逻辑(这就是为什么我对从另一个调用一个dao持怀疑态度)。还是应

  • 我正在使用ZXING1.7库开发J2ME条形码扫描器,因为1.7是支持J2ME的最新版本。 由于条形码功能已经作为这个Zxing的一部分出现了,所以我需要从我的组件MIDlet调用ZxingMidlet.java。 由于我对J2ME非常陌生,所以我不知道如何从另一个MIDlet调用ZxingMidlet。如果有人已经在J2ME上工作过/有这方面的经验,请提供您的投入/支持。 这对我会有很大的帮助。

  • 我尝试使用Firebase为Android提供推送通知。但我面临着非常奇怪的问题。当我在前台发送推送时,一切正常。当我在后台发送推送时(我只发送数据),一切都正常,直到我回到前台,然后回到后台。 当我的应用程序第二次转到后台时,不会调用我的FirebaseMessagingService。另外,请注意,我使用的是Android Emulator。代码: AndroidManifest。xml: 服