gpt4 book ai didi

android - 如何在 RxAndroid 2.0 中正确过滤/计数?

转载 作者:搜寻专家 更新时间:2023-11-01 07:44:05 25 4
gpt4 key购买 nike

给定一个返回可观察的账单列表的存储库:

Observable<List<Bill>> getBills();

我希望仅在未支付一张或多张账单时显示 View 。我正在尝试以下代码:

repository.getBills()
.flatMapIterable(bills -> bills)
.filter(bill -> !bill.isPaid())
.count()
.map(count -> count > 0)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(overdue -> {
if (!overdue) return;
mView.showWarning();
});

但是 onSuccessonError 都没有被调用。

我知道存储库包含至少一个逾期项目,因为以下代码打印未支付的账单:

repository.getBills()
.subscribeOn(Schedulers.io())
.flatMapIterable(bills -> bills)
.filter(bill -> !bill.isPaid())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
bill -> Timber.d(bill.toString()),
e -> Timber.e(e.getMessage(), e),
() -> Timber.d("Completed")
);

最佳答案

长话短说:
如果它从未完成,则 count 不起作用。如果要检查未付款项,可以使用 any 运算符、takeUntiltakeWhile。跳转到此答案中的第三项。

完整答案:

存在三种可能的问题:

  1. 它可能发生在 showWarning() 内部。我运行了以下代码并且它打印 DUE:

    findViewById(R.id.doSomething).setOnClickListener(v -> {
    clearWarning();
    getBills()
    .subscribeOn(Schedulers.io())
    .flatMapIterable(bills -> bills)
    .filter(bill -> !bill.isPaid())
    .count()
    .map(count -> count > 0)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(
    due -> {
    if (!due) return;
    showWarning();
    }
    );
    });

    使用以下 getBills():

    private Observable<List<Bill>> getBills() {
    Bill sampleBill = new Bill();
    List<Bill> bills = new ArrayList<>(1);
    bills.add(sampleBill);
    return Observable.just(bills);
    }

    Bill 是一个虚拟类,只在 isPaid() 中返回 false:

    class Bill {
    public boolean isPaid() {
    return false;
    }
    }

    我有一个 TextView 用于 showWarning()clearWarning() 并且它正确打印“到期”

  2. 另一个选项是您的 getBills() 中的问题。是否源代码是否成功完成(我的意思是,它调用了 onComplete())?您可以手动调用它或使用 Single,但您需要在 flatMapIterable() 之前调用 toObservable()

    根据 documentation :

    If the source Observable terminates with an error, Count will pass this error notification along without emitting an item first. If the source Observable does not terminate at all, Count will neither emit an item nor terminate.

  3. 如果您不能在 getBills() 中更改 Observable,但只需要检测何时有未支付的账单,您可以使用 takeWhiletakeUntilany:

    findViewById(R.id.doSomething).setOnClickListener(v -> {
    clearWarning();
    getBills()
    .flatMapIterable(bills -> bills)
    .takeUntil(bill -> !bill.isPaid())
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(
    bill -> {
    Log.d("POTATO", "Number: " + bill.getNumber() + " Paid: " + bill.isPaid());
    },
    e -> Log.e("POTATO", "Error"),
    () -> {
    Log.d("POTATO", "Complete");
    showWarning();
    }
    );
    }); }

    对于此示例,我将 getBills() 更改为永不完成:

     private Observable<List<Bill>> getBills() {
    List<Bill> bills = new ArrayList<>();
    bills.add(new Bill(1, true));
    bills.add(new Bill(2, true));
    bills.add(new Bill(3, false));
    bills.add(new Bill(4, false));
    return Observable.create(
    emitter -> emitter.onNext(bills)
    );
    }

    为了显示发出的是哪个项目,现在 Bill 类如下所示如下:

    class Bill {

    private final int number;
    private boolean isPaid;

    Bill(int number, boolean isPaid) {
    this.number = number;
    this.isPaid = isPaid;
    }

    int getNumber() {
    return number;
    }

    boolean isPaid() {
    return isPaid;
    }
    }

    Log 打印

    人数:1 付费:true
    人数:2 付费:true
    人数:3 付费:false
    完成

    然后 showWarning() 被调用。 takeWhile 当然应该有与 takeUntil 相反的返回值。两者都会获取付费项目并在有未付费项目时停止,但 takeWhile 甚至不会发出未付费项目(Number: 3: Paid: false 不会出现在日志中,但它会在 2) 之后立即完成。 any 将获得满足条件的任何项目,这对您来说可能就足够了。请注意,这是一个完全不同的解决方案。如果源只发出付费项目,它将永远不会完成。但是你应该在某处有一个unsubscribe

关于android - 如何在 RxAndroid 2.0 中正确过滤/计数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48410420/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com