如何显示来自flatMap运算符的可观察对象的内容

时间:2018-08-07 14:08:17

标签: android rx-java observable rx-java2 rx-android

我试图了解.fromCallable的工作原理,因此创建了以下简单示例。如下所示,我将整数数组转换为可观察值,然后 我想显示flatMap的内容。因此,我使用.map遍历数组中的所有项目,但是观察者返回

MainActivitygetFromCallableObserver: onNext->o: [I@18fb0dbb

我希望onNext()的调用与数组中项目的数目一样多,并且每次调用onNext()时,我都希望将数组中的每个项目都保存起来。

请让我知道如何将整数数组转换为可观对象,然后应用.map运算符,以便观察者中的onNext显示每一项

代码

private void executeRxFromCallable() {
    final int[] delayValue = {-1};
    int[] nums = new int[7];
    Observable.fromCallable(new Callable<int[]>() {
        @Override
        public int[] call() throws Exception {
            while(++delayValue[0] < 7) {
                Thread.sleep(1000);
                Log.i(TAG, "delayValue[0]: " + delayValue[0]);
                nums[delayValue[0]] = delayValue[0] * 10;
            }
            Log.i(TAG, "total delay: " + delayValue[0]);
            Log.i(TAG, "nums.length: " + nums.length);
            return nums;
        }
    })
            .flatMap(new Function<int[], ObservableSource<?>>() {
                @Override
                public ObservableSource<?> apply(@NonNull int[] ints) throws Exception {
                    return Observable.fromArray(ints);
                }
            })
            .map(new Function<Object, Object>() {
                @Override
                public Object apply(@NonNull Object o) throws Exception {
                    return o;
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe( this.getFromCallableObserver());

}

private Observer<? super Object> getFromCallableObserver() {
    return new Observer<Object>() {
        public void onSubscribe(@NonNull Disposable d) {
            Log.i(TAG + "getFromCallableObserver", "onSubscribe->d: " + d);

        }

        @Override
        public void onNext(@NonNull Object o) {
            Log.i(TAG + "getFromCallableObserver", "onNext->o: " + String.valueOf(o));
        }

        @Override
        public void onError(@NonNull Throwable e) {
            Log.i(TAG + "getFromCallableObserver", "onError->e: " + e.getMessage());
        }

        @Override
        public void onComplete() {
            Log.i(TAG + "getFromCallableObserver", "onComplete");
        }
    };
}

结果

MainActivitygetFromCallableObserver: onNext->o: [I@18fb0dbb

2 个答案:

答案 0 :(得分:1)

如果您只想使用flatMap将值列表转换为单独的事件,则可以借助Observable.fromIterable(...)进行如下操作:

@RunWith(RobolectricTestRunner.class)
public class RxTest {
    @Test
    public void testFromCallableUsage() throws Exception {
        Observable.fromCallable(() -> {
            List<Integer> list = new ArrayList<>();
            for (int i = 0; i < 7; i++) {
                list.add(i + 1);
                //do your sleep here
            }
            return list;
        })
            .flatMap(array -> {
                return Observable.fromIterable(array);
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(result -> System.out.println("Value : " + result),
              throwable -> System.out.println(throwable.getMessage()));

        Thread.sleep(1000);
    }
}

输出

  

值:1

     

值:2

     

值:3

     

值:4

     

值:5

     

值:6

     

值:7

实际上,为了发送7个事件,它们之间的时间间隔为1000毫秒,您也可以使用intervalRange。然后,在您的map中,您可以执行所需的任何计算/请求,然后通过Observable.just(...)进一步发送它们:

@RunWith(RobolectricTestRunner.class)
public class RxJavaMergeTest {
    @Test
    public void testFromCallableUsage() {
        Observable.intervalRange(0, 7, 0, 1000,  TimeUnit.MILLISECONDS)
            .concatMap(element -> {
                //do whatever modifications you need with your value and then send it
                return Observable.just(element);
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(result -> System.out.println("Value : " + result),
              throwable -> System.out.println(throwable.getMessage()));

        // wait until all the tasks complete
        Thread.sleep(10 * 1000);
    }
}

答案 1 :(得分:0)

在您的情况下,问题是Observable.fromArray(ints);在地图函数中返回一个数组,而不是每个int项。如果您只想使用简单的int而不是数组来尝试foomCallable的工作,将会更容易理解。

但是我不确定您尝试从示例中看到什么。

可能是这样的吗?

private void executeRxFromCallable() {
        final int value = 42;
        Observable.fromCallable(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                Thread.sleep(1000);
                return value;
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe( this.getFromCallableObserver());

    }

    private Observer<Integer> getFromCallableObserver() {
        return new Observer<Integer>() {
            public void onSubscribe(@NonNull Disposable d) {
                Log.i(TAG + "getFromCallableObserver", "onSubscribe->d: " + d);

            }

            @Override
            public void onNext(@NonNull Integer o) {
                Log.i(TAG + "getFromCallableObserver", "onNext->o: " + String.valueOf(o));
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.i(TAG + "getFromCallableObserver", "onError->e: " + e.getMessage());
            }

            @Override
            public void onComplete() {
                Log.i(TAG + "getFromCallableObserver", "onComplete");
            }
        };
    }