RxJava - Debug chain that seems to block forever

喜欢而已 提交于 2020-01-17 04:40:11

问题


I'm running the following code:

List<GroupedObservable<BcxToDoList, BcxToDo>> mToDoList;

mToDoList = bcxClient
  .fetchToDos()
  .flatMap(new Func1<List<BcxToDo>, Observable<BcxToDo>>() {
    @Override
    public Observable<BcxToDo> call(List<BcxToDo> bcxToDos) {
      return Observable.from(bcxToDos);
    }
  })
  .groupBy(new Func1<BcxToDo, BcxToDoList>() {
    @Override
    public BcxToDoList call(BcxToDo bcxToDo) {
      return bcxToDo.toDoList;
    }
  })
  .toList()
  .toBlocking()
  .single();

When I step into this code in Android Studio, the code blocks indefinitely. If I trap this using subscribe(), there are no exceptions.

What's the best way to debug what's going on?

UPDATE

Following @dwursteisen's advice, I used .doOnNext() to see what the .groupBy() was emitting. It was creating the output I expected, it just never sent the onCompleted notification.

According to these tickets, in RxJava this is by design. Each GroupedObservable must be dealt with in order for the toList operator to work.

So here's my revised code:

List<BcxToDoList> mToDoList;

mToDoList = bcxClient
  .fetchToDos()
  .flatMap(new Func1<List<BcxToDo>, Observable<BcxToDo>>() {
    @Override
    public Observable<BcxToDo> call(List<BcxToDo> bcxToDos) {
      return Observable.from(bcxToDos);
    }
  })
  .groupBy(new Func1<BcxToDo, BcxToDoList>() {
    @Override
    public BcxToDoList call(BcxToDo bcxToDo) {
      return bcxToDo.toDoList;
    }
  })
  .flatMap( new Func1<GroupedObservable<BcxToDoList, BcxToDo>, Observable<BcxToDoList>>() {
    @Override
    public Observable<BcxToDoList> call(final GroupedObservable<BcxToDoList, BcxToDo> bcxToDoListBcxToDoGroupedObservable) {
      return bcxToDoListBcxToDoGroupedObservable
        .toList()
        .flatMap( new Func1<List<BcxToDo>, Observable<BcxToDoList>>() {
          @Override
          public Observable<BcxToDoList> call(List<BcxToDo> bcxToDos) {
            bcxToDoListBcxToDoGroupedObservable.getKey().toDos.addAll( bcxToDos );

            return Observable.just( bcxToDoListBcxToDoGroupedObservable.getKey() );
          }
        });
    }
  })

  .toList()

  .toBlocking()
  .single();

Not quite as elegant as the first code snippet, but at least it no longer blocks! If there's anything I can do to make the new code snippet more readable, I'd appreciate any advice.


回答1:


Debug can be tricky with RxJava.

You can add .doOnNext() call that will allow you to display RxJava notification and see what's going one.

According to your code, I think that your code block as you use the toList operator that will emit only if the Observable complete.

I think that your stream doesn't complete so toList never emits and then your code block forever.




回答2:


This SO answer provides the correct way to debug RxJava:

By now I can't reproduce the problem but I've found rxdebug-java a very good tool for debugging.

It's use is simple: add the library as a dependency and at application start register a listener:

RxJavaPlugins.getInstance().registerObservableExecutionHook(new DebugHook(new DebugNotificationListener() {
  public Object onNext(DebugNotification n) {
      Log.v(TAG,"onNext on "+n);
      return super.onNext(n);
  }


    public Object start(DebugNotification n) {
        Log.v(TAG,"start on "+n);
        return super.start(n);
    }


    public void complete(Object context) {
        super.complete(context);
        Log.v(TAG,"onNext on "+context);
    }

  public void error(Object context, Throwable e) {
      super.error(context, e);
      Log.e(TAG,"error on "+context);
  }
}));


来源:https://stackoverflow.com/questions/29442032/rxjava-debug-chain-that-seems-to-block-forever

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!