Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java `distinctUntilChanged`调用onNext后如何允许同一项_Java_Android_Rx Java_Rx Java2 - Fatal编程技术网

Java `distinctUntilChanged`调用onNext后如何允许同一项

Java `distinctUntilChanged`调用onNext后如何允许同一项,java,android,rx-java,rx-java2,Java,Android,Rx Java,Rx Java2,我有一个observable,它不断地发射项目,我需要处理每个项目(处理函数需要一些时间)。因此,在处理一个项目的同时,如果另一个项目发出相同的值, 我可以忽略它,因为同样的工作已经在进行中。但一旦处理了当前项(并称为onNext)。如果以后有同样的要求,我会允许的。 我使用了distinctUntildChanged操作符,但我可以看到,即使最后一个项目完成了处理并调用了onNext,如果当前项目与最后一个项目相同,它也不允许 我有一个样本来证明这个问题 我有一节课 class User {

我有一个observable,它不断地发射项目,我需要处理每个项目(处理函数需要一些时间)。因此,在处理一个项目的同时,如果另一个项目发出相同的值, 我可以忽略它,因为同样的工作已经在进行中。但一旦处理了当前项(并称为onNext)。如果以后有同样的要求,我会允许的。 我使用了
distinctUntildChanged
操作符,但我可以看到,即使最后一个项目完成了处理并调用了
onNext
,如果当前项目与最后一个项目相同,它也不允许

我有一个样本来证明这个问题

我有一节课

class User {
    String id;
    String name;

    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        User obj1 = (User) obj;
        return id.equals(obj1.id);
    }

    @Override
    public String toString() {
        return name;
    }
}
和一个可观察的(主体)

我发出这样的值

    for (int i = 0; i < 20; i++) {
        Thread.sleep(1000);            
        mSubject.onNext(new User(String.valueOf(1), "User " + i)); // all `User`s have same id
    }
这里的所有对象都相同(等于方法检查id)。正如您所看到的,第一次处理它花费了
user0
,需要5秒钟,在此期间,我可以忽略传入的项目, 但是在此之后,
onNext:User 0
我应该允许相同的用户请求,但是
distinctunitrichanged
不允许,因为它将最后一个值eqal指定给了相同的用户,我该怎么做?
希望我的问题是清楚的。

您可以使用
groupBy()
操作符来区分
用户的请求。在每一个可观察的场景中,你可以安排只处理最新的发射

mSubject
  .doOnNext(i -> Log.d(TAG, "emitted: " + i))
  .observeOn(Schedulers.io())
  .groupBy( user -> user )
  .flatMap( userObserverable -> userObservable
                                  .onBackpressureDrop()
                                  .map(user -> {
                                    Log.d(TAG, "processing " + user);
                                    Thread.sleep(5000); // processing takes 5 seconds
                                    return user;
                                  })
  .subscribe(user -> Log.d(TAG, "onNext: " + user.name));

groupBy()
操作符为每个用户创建一个可观察对象。新用户将为他们创建一个新的可观察对象。每个用户将根据其自身的可观察性排放,如果下游不接受排放,则
onBackpressureDrop()
将丢弃用户。

因此,您可以通过
可流动
和正确的
BackpressureStragy
实现这一点。问题是在执行
observeOn
时没有设置缓冲区大小。你可以试试这个(尽管是科特林):

输出如下所示:

emitting 0
consuming 0
emitting 1
emitting 2
emitting 3
emitting 4
emitting 5
consuming 5
emitting 6
emitting 7
emitting 8
emitting 9
emitting 10
consuming 10
emitting 11
emitting 12
emitting 13
emitting 14
调用
observeOn(调度器)
时,如果我没有弄错的话,背压的默认缓冲区大小应该是128

您可以尝试将上面示例中的缓冲区大小更改为3。你会得到:

emitting 0
consuming 0
emitting 1
...
emitting 5
consuming 1
emitting 6
...
emitting 10
consuming 2
emitting 11
...
emitting 15
consuming 15
emitting 16
...
emitting 20
consuming 16
emitting 21
...

我想你需要使用一个带有下拉式BackPressureStategy的Flowable。我尝试了
BackPressureStategy.LATEST
BackPressureStategy.DROP
,但5秒后,它开始
处理用户1
,并且它将处理所有项目,我只需要处理最新的项目。比如在第5秒之后,我只需要最新的值,我可以跳过前面的所有值。我不确定我是否真的理解了这个问题,据我所知,你根本不想
distinctUntilChanged
,这听起来像是一个背压策略问题。你能更新你的问题吗?我需要处理每一个最新的用户。如果同一个用户来了,如果已经有一个在进行中,我可以忽略。如果相同的用户在处理旧的相同的用户之后,我应该考虑它。希望它现在清楚了?是的,这样就很清楚了,那么你应该可以用一个FlowTable来实现这一点,因为你的代码没有编译
.onBackPressureDrop()
方法在
userObservable
onBackPressureDrop()
中不可用,应使用小写字母“p”拼写。但它仍然无法检测到。请看。现在我运行的是IntelliJ而不是android studio,这是唯一的区别。我已经正确地添加了rxJava2依赖项。(这是一个在Intellij中运行的maven项目)Hmmm.
GroupedObservable
在RxJava2中没有背压处理,正如您所期望的那样。但是,
GroupedFlowable
可以。这意味着您在构建链时必须使用
可流动的
而不是
可观察的
。现在,我用
PublishProcessor
更改了
主题
,现在您的代码可以编译,但结果仍然是一样的!!正是我想要的。非常感谢。还有一个问题。第二个参数
delayError
实际上是什么意思?我没有从文档中正确地得到它。此外,buffersize是它可以容纳的项目数?或者内存大小(以字节为单位)?因此,
delayError
的文档表示“指示onError通知是否可能在调度边界另一侧的onNext通知之前剪切。如果为真,则以onError结尾的序列将按照从上游接收到的相同顺序重新播放”抱歉,我不确定它实际上是做什么的:)缓冲区大小是应用BackPressureStragy之前它将保留的项目数。
mSubject
  .doOnNext(i -> Log.d(TAG, "emitted: " + i))
  .observeOn(Schedulers.io())
  .groupBy( user -> user )
  .flatMap( userObserverable -> userObservable
                                  .onBackpressureDrop()
                                  .map(user -> {
                                    Log.d(TAG, "processing " + user);
                                    Thread.sleep(5000); // processing takes 5 seconds
                                    return user;
                                  })
  .subscribe(user -> Log.d(TAG, "onNext: " + user.name));
Observable.interval(100, TimeUnit.MILLISECONDS)
    .doOnNext { println("emitting $it") }
    .toFlowable(BackpressureStrategy.LATEST)
    .observeOn(Schedulers.io(), false,1)
    .subscribeOn(Schedulers.io())
    .subscribe {
        println("consuming $it")
        Thread.sleep(500)
    }
emitting 0
consuming 0
emitting 1
emitting 2
emitting 3
emitting 4
emitting 5
consuming 5
emitting 6
emitting 7
emitting 8
emitting 9
emitting 10
consuming 10
emitting 11
emitting 12
emitting 13
emitting 14
emitting 0
consuming 0
emitting 1
...
emitting 5
consuming 1
emitting 6
...
emitting 10
consuming 2
emitting 11
...
emitting 15
consuming 15
emitting 16
...
emitting 20
consuming 16
emitting 21
...