React native 在RxJava订阅链中,我应该在哪里设置BackPressureBuffer(n)?
我正在尝试热修复现有的React本机库,并在中添加onBackPressureBuffer() 我知道这很难看,但我现在没有时间提交公关,有一个解决问题的方法。 我这样做是因为事件发射器的工作频率是200Hz。我需要一种安全的方法来缓冲本机端的项目,同时在JavaScript端以自己的速度使用它们 因此,代码如下所示:React native 在RxJava订阅链中,我应该在哪里设置BackPressureBuffer(n)?,react-native,rx-java,react-native-ble-plx,React Native,Rx Java,React Native Ble Plx,我正在尝试热修复现有的React本机库,并在中添加onBackPressureBuffer() 我知道这很难看,但我现在没有时间提交公关,有一个解决问题的方法。 我这样做是因为事件发射器的工作频率是200Hz。我需要一种安全的方法来缓冲本机端的项目,同时在JavaScript端以自己的速度使用它们 因此,代码如下所示: final Subscription subscription = Observable.defer(new Func0<Observable<Obse
final Subscription subscription = Observable.defer(new Func0<Observable<Observable<byte[]>>>() {
@Override
public Observable<Observable<byte[]>> call() {
int properties = gattCharacteristic.getProperties();
BluetoothGattDescriptor cccDescriptor = gattCharacteristic
.getDescriptor(Characteristic.CLIENT_CHARACTERISTIC_CONFIG_UUID);
NotificationSetupMode setupMode = cccDescriptor != null ? NotificationSetupMode.QUICK_SETUP
: NotificationSetupMode.COMPAT;
if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
return connection.setupNotification(gattCharacteristic, setupMode);
}
if ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) {
return connection.setupIndication(gattCharacteristic, setupMode);
}
return Observable.error(new CannotMonitorCharacteristicException(gattCharacteristic));
}
}).onBackpressureBuffer(1000) <---- Here is my modification
.flatMap(new Func1<Observable<byte[]>, Observable<byte[]>>() {
@Override
public Observable<byte[]> call(Observable<byte[]> observable) {
return observable;
}
}).doOnUnsubscribe(new Action0() {
@Override
public void call() {
promise.resolve(null);
transactions.removeSubscription(transactionId);
}
}).subscribe(new Observer<byte[]>() {
@Override
public void onCompleted() {
promise.resolve(null);
transactions.removeSubscription(transactionId);
}
@Override
public void onError(Throwable e) {
errorConverter.toError(e).reject(promise);
transactions.removeSubscription(transactionId);
}
@Override
public void onNext(byte[] bytes) {
characteristic.logValue("Notification from", bytes);
WritableArray jsResult = Arguments.createArray();
jsResult.pushNull();
jsResult.pushMap(characteristic.toJSObject(bytes));
jsResult.pushString(transactionId);
sendEvent(Event.ReadEvent, jsResult);
}
});
final Subscription=Observable.defer(新函数0(){
@凌驾
公共可观测呼叫(){
int properties=gattCharacteristic.getProperties();
蓝牙GattDescriptor CCCDDescriptor=gattCharacteristic
.getDescriptor(Characteristic.CLIENT\u Characteristic\u CONFIG\u UUID);
NotificationSetupMode setupMode=CCCDDescriptor!=null?NotificationSetupMode.QUICK\u设置
:NotificationSetupMode.COMPAT;
if((属性和BluetoothGattCharacteristic.PROPERTY_NOTIFY)!=0){
返回连接.setupNotification(gattCharacteristic,setupMode);
}
if((属性和BluetoothGattCharacteristic.PROPERTY_指示)!=0){
回路连接。设置指示(gattCharacteristic,设置模式);
}
返回可观察错误(新的CannotMonitorCharacteristicException(gattCharacteristic));
}
}).onBackpressureBuffer(1000)正如您所说,您正面临一个react native
库的问题,并且上面的代码以前确实抛出了MissingBackpressureException
从.onBackpressureDrop()
的Javadoc(粗体):
指示发射项目的速度快于其观察者消耗项目的可观察者丢弃项目,
与其发射,不如发射观察者不准备观察的项目。
如果下游请求计数达到0,则可观察对象将不调用{@code onNext},直到
观察者再次调用{@code request(n)}以增加请求计数
背压:
操作员接受来自下游的背压,并以无界形式消耗源{@code Observable}
方式(即不向其施加背压)。
调度程序:
默认情况下,{@code onBackpressureDrop}不会在特定的{@link Scheduler}上运行。
您可以看到链中的下一个操作符是.flatMap()
、.dounsubscribe()
和.subscribe()
从.flatMap()
的Javadoc中,关于背压:
背压:
操作员接受来自下游的背压。外部{@code Observable}被消耗
在无界模式下(即,不向其施加背压)。内部{@code-Observable}应该遵守
背压;如果违反,操作员可能会发出信号{@code missingbackpressureeexception}
Javadoc.dounsubscribe()
:
背压:
{@code dounsubscribe}不与背压请求或价值传递交互;背压
行为在其上游和下游之间保持不变
和.subscribe()
:
背压:
运算符以无限制的方式使用源{@code Observable}(即,no
对其施加背压)
如您所见,下面的.onBackpressure*()
运算符都不会对其施加背压。您需要添加一个运算符,该运算符在.onBackpressure*()
之后立即执行此操作。其中一个操作符是.observeOn(调度器)
Javadoc.observeOn()
:
背压:
此运算符接受来自下游的背压,并期望来自源{@code Observable}。违反这个
期望值将导致{@code missingbackpressureeexception}。这是异常发生时最常见的运算符
弹出窗口;寻找不支持背压的供应链上游来源,
例如{@code interval}、{@code timer}、{code PublishSubject}或{@code BehaviorSubject}并应用任何
在应用{@code-observeOn}自身之前,{@code-onbackpressurexx}操作符的
因此,一个可行的代码可以如下所示:
final Subscription subscription = Observable.defer(new Func0<Observable<Observable<byte[]>>>() {
@Override
public Observable<Observable<byte[]>> call() {
int properties = gattCharacteristic.getProperties();
BluetoothGattDescriptor cccDescriptor = gattCharacteristic
.getDescriptor(Characteristic.CLIENT_CHARACTERISTIC_CONFIG_UUID);
NotificationSetupMode setupMode = cccDescriptor != null ? NotificationSetupMode.QUICK_SETUP
: NotificationSetupMode.COMPAT;
if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
return connection.setupNotification(gattCharacteristic, setupMode);
}
if ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) {
return connection.setupIndication(gattCharacteristic, setupMode);
}
return Observable.error(new CannotMonitorCharacteristicException(gattCharacteristic));
}
})
.flatMap(new Func1<Observable<byte[]>, Observable<byte[]>>() {
@Override
public Observable<byte[]> call(Observable<byte[]> observable) {
return observable;
}
})
.doOnUnsubscribe(new Action0() {
@Override
public void call() {
promise.resolve(null);
transactions.removeSubscription(transactionId);
}
})
.onBackpressureBuffer(1000) // <---- Here is my modification
.observeOn(Schedulers.trampoline()) // <---- an operator that does backpressure the above
.subscribe(new Observer<byte[]>() {
@Override
public void onCompleted() {
promise.resolve(null);
transactions.removeSubscription(transactionId);
}
@Override
public void onError(Throwable e) {
errorConverter.toError(e).reject(promise);
transactions.removeSubscription(transactionId);
}
@Override
public void onNext(byte[] bytes) {
characteristic.logValue("Notification from", bytes);
WritableArray jsResult = Arguments.createArray();
jsResult.pushNull();
jsResult.pushMap(characteristic.toJSObject(bytes));
jsResult.pushString(transactionId);
sendEvent(Event.ReadEvent, jsResult);
}
});
final Subscription=Observable.defer(新函数0(){
@凌驾
公共可观测呼叫(){
int properties=gattCharacteristic.getProperties();
蓝牙GattDescriptor CCCDDescriptor=gattCharacteristic
.getDescriptor(Characteristic.CLIENT\u Characteristic\u CONFIG\u UUID);
NotificationSetupMode setupMode=CCCDDescriptor!=null?NotificationSetupMode.QUICK\u设置
:NotificationSetupMode.COMPAT;
if((属性和BluetoothGattCharacteristic.PROPERTY_NOTIFY)!=0){
返回连接.setupNotification(gattCharacteristic,setupMode);
}
if((属性和BluetoothGattCharacteristic.PROPERTY_指示)!=0){
回路连接。设置指示(gattCharacteristic,设置模式);
}
返回可观察错误(新的CannotMonitorCharacteristicException(gattCharacteristic));
}
})
.flatMap(新函数1(){
@凌驾
公共可观察呼叫(可观察){
可观测收益;
}
})
.dounsubscribe(新操作0(){
@凌驾
公开作废通知(){
承诺。解决(空);
transactions.removeSubscription(transactionId);
}
})
.onBackpressureBuffer(1000)//我会试试,几个小时后再回来找你。请继续关注。这似乎正在发挥作用,等待更多的时间确认。我以前不知道RxJava的实现细节。我曾经在c#中使用被动扩展,默认情况下有缓冲。此外,在我的头脑中,onBackPressureBuffer将应用于下游,而不需要其他任何东西