在RxJava2中的zip运算符中发生错误时,如何删除源?

时间:2019-05-19 09:21:00

标签: java rx-java2

我从Observables中包装了来自各种设备的一些传感器输入。 我想取这些传感器值的平均值,因此Zip运算符似乎很合适。现在的问题是,当与其中一台设备的连接失败时,我不希望整个过程中断。标准行为是,如果源给出错误,则所有源都将终止,并且可从zip运算符本身观察到。 此标准行为有两个问题: 1)当一个源给出错误时,其他源将终止,IE将失去连接。然后,延迟操作员必须重新建立此连接,这需要一些时间。我想在移除设备时无缝过渡。 2)在失败的源上执行.onErrorResumeNext()并不是一种选择,因为这又需要一个源。进行Observable.just(0).repeat()是不可接受的,因为在取值的平均值时对0值进行特殊例外并不干净。

我想要实现的行为是无缝地停止监听发出错误的可观察对象,然后继续处理仍然有效的对象。 有人知道如何执行此操作吗?

编辑: 我设法使系统正常运行,但没有达到我想要的方式。通过以下代码段进行说明:

public FusedHeartRateSensor(HeartRateSensor... devices) {
    super("FusedHeartRateSensor", IoTType.TYPE_HEART_RATE_SENSOR, new FusedConnector(), devices);
    init();
}

private void init() {
    Observable.fromIterable(fusedDevices)
            .flatMap(hrs -> hrs.monitorConnection())
            .subscribeOn(Schedulers.newThread())
            .subscribe(
                    state -> {
                        //Als iets verandert met de staat van de geconnecteerde toestellen moet
                        //de deviceChangeObservable op de hoogte gebracht worden
                        refreshConnectedDevices();
                    },
                    throwable -> {
                        Log.e(TAG, throwable.getLocalizedMessage());
                        throwable.printStackTrace();
                    }
            );
}

private void refreshConnectedDevices() {
    Log.i(TAG, "Refreshing enabled fused devices");
    List<HeartRateSensor> devices = fusedDevices.stream()
            .filter(Connectable::isConnected)
            .collect(Collectors.toList());

    deviceChangeObservable.onNext(devices);
}

private Observable<Integer> getMeanObservable(List<Observable<List<Integer>>> observables) {
    System.out.println();
    return Observable.zip(observables, objects -> getMean(Arrays.stream(objects).map(o -> (List<Integer>) o).filter(l -> !l.isEmpty()).map(this::getMean).collect(Collectors.toList())));
}

还有要求监控的地方...

@Override
public Observable<Integer> monitorHeartRate() {
    ReplaySubject<Integer> resultObservable = ReplaySubject.create();
    CompositeDisposable disposable = new CompositeDisposable();

    deviceChangeObservable.subscribe(
                    sensors -> {
                        Log.i(TAG, "Switched to new sources");
                        getMeanObservable(sensors.stream()
                                .map(s -> s.monitorHeartRate()
                                        .buffer(1, TimeUnit.SECONDS))
                                .collect(Collectors.toList()))
                                .subscribe(
                                        t -> {
                                            resultObservable.onNext(t);
                                            System.out.println();
                                        },
                                        throwable -> {
                                            throwable.printStackTrace();
                                            System.out.println();

                                        }
                                );
                    },
                    throwable -> {
                        Log.e(TAG, throwable.getLocalizedMessage());
                        throwable.printStackTrace();
                        System.out.println();
                    }
            );

    return resultObservable;
}

此问题是,当拉链操作器中的传感器发生故障时,拉链中的所有其他可观察物停止。我当前的解决方案是重试连接,并仅使用仍处于连接状态的设备的可观察对象设置可观察到的新zip。问题在于这不是无缝的。我也尝试过使用defer和retry,但这与上面的代码具有相同的结果。

0 个答案:

没有答案