我想执行一项操作,该操作在订阅Observable
后执行。目前我执行一些与BLE相关的操作,比如读取我的连接的rssi:
public class BleGattOperations {
private class BleGattCallback extends BluetoothGattCallback {
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
readRssiSubject.onNext(new RssiState(gatt, rssi, status));
}
}
// Defined in Constructor
private final BluetoothGattCallback callback;
// Defined in Constructor
private BluetoothGatt gatt;
private final Subject<RssiState, RssiState> readRssiSubject = PublishSubject.create();
public Observable<RssiState> readRssi() {
return readRssiSubject
.doOnSubscribe(() -> {
gatt.readRemoteRssi();
})
.take(1);
}
}
在readRssi()
- 方法中,我订阅了readRssiSubject
,该BleGattCallback.onReadRemoteRssi-Method()
会发出gatt.readRemoteRssi()
中的项目。可以通过doOnSubscribe()
- 块内的readRssiSubject
操作触发读取rssi操作。
不幸的是,doOnSubscribe方法在之前执行对主题的任何订阅都已完成,有时读取rssi操作的执行速度比完成onReadRemoteRssi
的订阅更快。因此,在public Observable<RssiState> readRssi() {
return readRssiSubject
.doOnSubscribe(() -> {
readRssiSubject.onNext(new RssiState());
})
.take(1);
}
- 方法执行后,新订阅的订阅者在订阅完成后没有收到rssi度量的结果。
也许一些实验性代码片段有助于理解基本上发生的事情:
from flask import Flask
app = Flask(__name__)
@app.route('/', methods=(['GET']))
def foo():
return "get"
@app.route('/', methods=(['POST']))
def bar():
return "post"
在对Subject / Observable进行订阅之后,有没有办法执行操作?
答案 0 :(得分:2)
来自doOnSubscribe
文档:
每个订阅都将导致调用给定的操作,除非源ObservableSource被引用计数,在这种情况下,源ObservableSource将为第一个订阅调用给定的操作 强>
PublishSubject
被引用计算。
虽然您使用的是PublishSubject
,但您似乎不会将消息从多个订阅者共享给它。在这种情况下,我会建议readRssi()
的以下实现:
public Observable<RssiState> readRssi() {
return Observable.create(emitter -> {
// this is invoked for every new subscriber
BluetoothGattCallback callback =
(BluetoothGatt gatt, int rssi, int status) -> {
emitter.onNext(new RssiState(gatt, rssi, status));
emitter.onComplete();
};
gatt.addListener(callback); // not sure about method name
gatt.readRemoteRssi(); // initiate read
});
}
create
方法见documentation and example。
答案 1 :(得分:1)
您可以使用concatEager触发多个Observable
的执行并保持其排放顺序:
Observable<Data> immediate = ...
Observable<Data> async = ...
Observable.concatEager(immediate, asnyc)
.subscribe();
当立即运行时,async的值会被缓冲,直到完成,然后序列切换到异步。请注意,concatEager
会从非当前来源预取有限数量的项目,也就是说,如果异步生成大量项目而立即仍处于活动状态,则会获得MissingBackpressureException
。
答案 2 :(得分:0)